/// <summary>Handles an exception when processing a batch response.</summary> /// <param name='service'>Data service doing the processing.</param> /// <param name="requestMessage">requestMessage holding information about the request that caused an error</param> /// <param name="responseMessage">responseMessage to which we need to write the exception message</param> /// <param name='exception'>Exception thrown.</param> /// <param name='batchWriter'>Output writer for the batch.</param> /// <param name="responseStream">Underlying response stream.</param> /// <param name="defaultResponseVersion">The data service version to use for response, if it cannot be computed from the requestMessage.</param> internal static void HandleBatchOperationError(IDataService service, AstoriaRequestMessage requestMessage, IODataResponseMessage responseMessage, Exception exception, ODataBatchWriter batchWriter, Stream responseStream, Version defaultResponseVersion) { Debug.Assert(service != null, "service != null"); Debug.Assert(exception != null, "exception != null"); Debug.Assert(batchWriter != null, "batchWriter != null"); Debug.Assert(service.Configuration != null, "service.Configuration != null"); Debug.Assert(CommonUtil.IsCatchableExceptionType(exception), "CommonUtil.IsCatchableExceptionType(exception)"); ErrorHandler handler = CreateHandler(service, requestMessage, exception, defaultResponseVersion); service.InternalHandleException(handler.exceptionArgs); if (requestMessage != null && responseMessage != null) { responseMessage.SetHeader(XmlConstants.HttpODataVersion, handler.responseVersion.ToString(2) + ";"); requestMessage.ProcessException(handler.exceptionArgs); // if ProcessBenignException returns anything, we can safely not write to the stream. if (ProcessBenignException(exception, service) != null) { return; } } if (requestMessage != null) { responseMessage = requestMessage.BatchServiceHost.GetOperationResponseMessage(); WebUtil.SetResponseHeadersForBatchRequests(responseMessage, requestMessage.BatchServiceHost); } else { responseMessage = batchWriter.CreateOperationResponseMessage(null); responseMessage.StatusCode = handler.exceptionArgs.ResponseStatusCode; } MessageWriterBuilder messageWriterBuilder = MessageWriterBuilder.ForError( null, service, handler.responseVersion, responseMessage, handler.contentType, null /*acceptCharsetHeaderValue*/); using (ODataMessageWriter messageWriter = messageWriterBuilder.CreateWriter()) { ODataError error = handler.exceptionArgs.CreateODataError(); WriteErrorWithFallbackForXml(messageWriter, handler.encoding, responseStream, handler.exceptionArgs, error, messageWriterBuilder); } }
/// <summary>Handles an exception before the response has been written out.</summary> /// <param name='exception'>Exception thrown.</param> /// <param name='service'>Data service doing the processing.</param> /// <returns>An action that can serialize the exception into a stream.</returns> internal static Action <Stream> HandleBeforeWritingException(Exception exception, IDataService service) { Debug.Assert(CommonUtil.IsCatchableExceptionType(exception), "CommonUtil.IsCatchableExceptionType(exception)"); Debug.Assert(exception != null, "exception != null"); Debug.Assert(service != null, "service != null"); AstoriaRequestMessage requestMessage = service.OperationContext.RequestMessage; Debug.Assert(requestMessage != null, "requestMessage != null"); ErrorHandler handler = CreateHandler(service, requestMessage, exception, VersionUtil.DataServiceDefaultResponseVersion); service.InternalHandleException(handler.exceptionArgs); service.OperationContext.ResponseMessage.SetHeader(XmlConstants.HttpODataVersion, handler.responseVersion.ToString(2) + ";"); requestMessage.ProcessException(handler.exceptionArgs); Action <Stream> action = ProcessBenignException(exception, service); if (action != null) { return(action); } MessageWriterBuilder messageWriterBuilder = MessageWriterBuilder.ForError( service.OperationContext.RequestMessage.AbsoluteServiceUri, service, handler.responseVersion, service.OperationContext.ResponseMessage, handler.contentType, service.OperationContext.RequestMessage.GetRequestAcceptCharsetHeader()); ODataMessageWriter messageWriter = messageWriterBuilder.CreateWriter(); ODataUtils.SetHeadersForPayload(messageWriter, ODataPayloadKind.Error); return(stream => { service.OperationContext.ResponseMessage.SetStream(stream); ODataError error = handler.exceptionArgs.CreateODataError(); WriteErrorWithFallbackForXml(messageWriter, handler.encoding, stream, handler.exceptionArgs, error, messageWriterBuilder); }); }