private static ExceptionHandlerContext CreateValidContext( HttpRequestMessage request, ExceptionContextCatchBlock catchBlock ) { return(CreateContext(CreateMinimalValidExceptionContext(catchBlock, request))); }
private static ExceptionContext CreateMinimalValidExceptionContext(ExceptionContextCatchBlock catchBlock, HttpRequestMessage request = null) { return(new ExceptionContext(new InvalidOperationException(), catchBlock) { Request = request, }); }
/// <summary> /// Asynchronously creates an error response. /// </summary> /// <remarks> /// This method returns a task that will set the headers and status code appropriately /// for an error response. If possible, it will also write the exception as an /// <see cref="HttpError"/> into the response body. /// <para> /// Any errors during the creation of the error response itself will be handled /// internally. The task returned from this method will not show as faulted. /// </para> /// </remarks> /// <param name="catchBlock">The catch block that caught the exception.</param> /// <param name="httpContextBase">The HTTP context.</param> /// <param name="request">The original request.</param> /// <param name="response">The original response whose content we could not write.</param> /// <param name="exception"> /// The exception caught attempting to write <paramref name="response"/>'s content. /// </param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns>A task that will create the error response.</returns> internal static Task <bool> CopyErrorResponseAsync(ExceptionContextCatchBlock catchBlock, HttpContextBase httpContextBase, HttpRequestMessage request, HttpResponseMessage response, Exception exception, CancellationToken cancellationToken) { return(CopyErrorResponseAsync(catchBlock, httpContextBase, request, response, exception, cancellationToken, ExceptionLogger, ExceptionHandler)); }
public void Log(Exception ex, HttpRequestMessage request, string catchBlockName) { var catchBlock = new ExceptionContextCatchBlock(catchBlockName, true, false); var exceptionContext = new ExceptionContext(ex, catchBlock, request); var exceptionLoggerContext = new ExceptionLoggerContext(exceptionContext); Log(exceptionLoggerContext); }
public void WhenLibLogExceptionLogger_LogAsyncExceptionLoggerContextCancellationTokenIsCalled() { var exceptionContextCatchBlock = new ExceptionContextCatchBlock("dummy", false, false); var exceptionContext = new ExceptionContext(_given.Exception, exceptionContextCatchBlock); var exceptionLoggerContext = new ExceptionLoggerContext(exceptionContext); var cancellationToken = new CancellationToken(); _actual.LibLogExceptionLogger.LogAsync(exceptionLoggerContext, cancellationToken).Wait(cancellationToken); }
private ExceptionHandlerContext GetAuthorizedExceptionContext(AuthenticationHeaderValue authHeader) { var ex = new Exception(); var catchBlock = new ExceptionContextCatchBlock("catch", false, false); var context = new ExceptionHandlerContext(new ExceptionContext(ex, catchBlock)); context.ExceptionContext.Request = new HttpRequestMessage(); context.ExceptionContext.Request.Headers.Authorization = authHeader; return(context); }
private static ExceptionHandlerContext CreateValidContext(HttpRequestMessage request, ExceptionContextCatchBlock catchBlock) { return(CreateContext(new ExceptionContext { Exception = new InvalidOperationException(), CatchBlock = catchBlock, Request = request })); }
public void HttpWebRoute_IsSameInstance() { // Arrange ExceptionContextCatchBlock first = WebHostExceptionCatchBlocks.HttpWebRoute; // Act ExceptionContextCatchBlock second = WebHostExceptionCatchBlocks.HttpWebRoute; // Assert Assert.Same(first, second); }
/// <summary>Determines whether the exception should be handled.</summary> /// <returns>true if the exception should be handled; otherwise, false.</returns> /// <param name="context">The exception handler context.</param> public virtual bool ShouldHandle(ExceptionHandlerContext context) { if (context == null) { throw new ArgumentNullException("context"); } ExceptionContext exceptionContext = context.ExceptionContext; ExceptionContextCatchBlock catchBlock = exceptionContext.CatchBlock; return(catchBlock.IsTopLevel); }
public void HttpControllerHandlerStreamContent_IsSpecifiedValue() { // Act ExceptionContextCatchBlock catchBlock = WebHostExceptionCatchBlocks.HttpControllerHandlerStreamContent; // Assert ExceptionContextCatchBlock expected = new ExceptionContextCatchBlock("HttpControllerHandler.StreamContent", isTopLevel: true); AssertEqual(expected, catchBlock); }
public void HttpWebRoute_IsSpecifiedValue() { // Act ExceptionContextCatchBlock catchBlock = WebHostExceptionCatchBlocks.HttpWebRoute; // Assert ExceptionContextCatchBlock expected = new ExceptionContextCatchBlock("HttpWebRoute", isTopLevel: true); AssertEqual(expected, catchBlock); }
public void HttpMessageHandlerAdapterStreamContent_IsSameInstance() { // Arrange ExceptionContextCatchBlock first = OwinExceptionCatchBlocks.HttpMessageHandlerAdapterStreamContent; // Act ExceptionContextCatchBlock second = OwinExceptionCatchBlocks.HttpMessageHandlerAdapterStreamContent; // Assert Assert.Same(first, second); }
internal static async Task WriteBufferedResponseContentAsync(HttpContextBase httpContextBase, HttpRequestMessage request, HttpResponseMessage response, IExceptionLogger exceptionLogger, IExceptionHandler exceptionHandler, CancellationToken cancellationToken) { Contract.Assert(httpContextBase != null); Contract.Assert(httpContextBase.Response != null); Contract.Assert(request != null); Contract.Assert(response != null); Contract.Assert(response.Content != null); HttpResponseBase httpResponseBase = httpContextBase.Response; // Return a task that writes the response body asynchronously. // We guarantee we will handle all error responses internally // and always return a non-faulted task, except for custom error handlers that choose to propagate these // exceptions. ExceptionDispatchInfo exceptionInfo; cancellationToken.ThrowIfCancellationRequested(); try { // Copy the HttpContent into the output stream asynchronously. await response.Content.CopyToAsync(httpResponseBase.OutputStream); return; } catch (OperationCanceledException) { // Propogate the canceled task without calling exception loggers or handlers. throw; } catch (Exception exception) { // Can't use await inside a catch block exceptionInfo = ExceptionDispatchInfo.Capture(exception); } Debug.Assert(exceptionInfo.SourceException != null); // If we were using a buffered stream, we can still set the headers and status code, and we can create an // error response with the exception. // We create a continuation task to write an error response that will run after returning from this Catch() // but before other continuations the caller appends to this task. // The error response writing task handles errors internally and will not show as faulted, except for // custom error handlers that choose to propagate these exceptions. ExceptionContextCatchBlock catchBlock = WebHostExceptionCatchBlocks.HttpControllerHandlerBufferContent; if (!await CopyErrorResponseAsync(catchBlock, httpContextBase, request, response, exceptionInfo.SourceException, exceptionLogger, exceptionHandler, cancellationToken)) { exceptionInfo.Throw(); } }
public void HttpMessageHandlerAdapterStreamContent_IsSpecifiedValue() { // Act ExceptionContextCatchBlock catchBlock = OwinExceptionCatchBlocks.HttpMessageHandlerAdapterStreamContent; // Assert ExceptionContextCatchBlock expected = new ExceptionContextCatchBlock("HttpMessageHandlerAdapter.StreamContent", isTopLevel: true); AssertEqual(expected, catchBlock); }
public void HttpControllerHandlerStreamContent_IsSameInstance() { // Arrange ExceptionContextCatchBlock first = WebHostExceptionCatchBlocks.HttpControllerHandlerStreamContent; // Act ExceptionContextCatchBlock second = WebHostExceptionCatchBlocks.HttpControllerHandlerStreamContent; // Assert Assert.Same(first, second); }
private static void AssertEqual(ExceptionContextCatchBlock expected, ExceptionContextCatchBlock actual) { if (expected == null) { Assert.Null(actual); return; } Assert.NotNull(actual); Assert.Equal(expected.Name, actual.Name); Assert.Equal(expected.IsTopLevel, actual.IsTopLevel); }
public void HttpControllerHandlerComputeContentLength_IsSpecifiedValue() { // Act ExceptionContextCatchBlock catchBlock = WebHostExceptionCatchBlocks.HttpControllerHandlerComputeContentLength; // Assert ExceptionContextCatchBlock expected = new ExceptionContextCatchBlock("HttpControllerHandler.ComputeContentLength", isTopLevel: true, callsHandler: false); AssertEqual(expected, catchBlock); }
public void HttpMessageHandlerAdapterBufferError_IsSpecifiedValue() { // Act ExceptionContextCatchBlock catchBlock = OwinExceptionCatchBlocks.HttpMessageHandlerAdapterBufferError; // Assert ExceptionContextCatchBlock expected = new ExceptionContextCatchBlock("HttpMessageHandlerAdapter.BufferError", isTopLevel: true, callsHandler: false); AssertEqual(expected, catchBlock); }
internal static async Task WriteStreamedResponseContentAsync( HttpContextBase httpContextBase, HttpRequestMessage request, HttpResponseMessage response, IExceptionLogger exceptionLogger, CancellationToken cancellationToken ) { Contract.Assert(httpContextBase != null); Contract.Assert(httpContextBase.Response != null); Contract.Assert(request != null); Contract.Assert(response != null); Contract.Assert(response.Content != null); Exception exception = null; cancellationToken.ThrowIfCancellationRequested(); try { // Copy the HttpContent into the output stream asynchronously. await response.Content.CopyToAsync(httpContextBase.Response.OutputStream); return; } catch (OperationCanceledException) { // Propogate the canceled task without calling exception loggers. throw; } catch (Exception ex) { exception = ex; } Contract.Assert(exception != null); ExceptionContextCatchBlock catchBlock = WebHostExceptionCatchBlocks.HttpControllerHandlerStreamContent; ExceptionContext exceptionContext = new ExceptionContext( exception, catchBlock, request, response ); await exceptionLogger.LogAsync(exceptionContext, cancellationToken); // Streamed content may have been written and cannot be recalled. // Our only choice is to abort the connection. httpContextBase.Request.Abort(); }
public IHttpActionResult Record(ClientExceptionModel model) { // Create the exception and exception context var exception = new ClientException(model); var catchBlock = new ExceptionContextCatchBlock("catchBlock", true, false); var context = new ExceptionContext(exception, catchBlock, Request); var loggerContext = new ExceptionLoggerContext(context); // Call elmah & log the exception var logger = new ExceptionHandling.ElmahExceptionLogger(); logger.Log(loggerContext); // Return return(StatusCode(HttpStatusCode.NoContent)); }
public IHttpActionResult Record(AngularExceptionModel model) { // Create the exception and exception context var exception = new AngularException(model.ToString()); var catchBlock = new ExceptionContextCatchBlock("catchBlock", true, false); var context = new ExceptionContext(exception, catchBlock, Request); var loggerContext = new ExceptionLoggerContext(context); // Call elmah & log the exception var logger = new ExceptionHandling.ElmahExceptionLogger(); logger.Log(loggerContext); // Return return(Ok()); }
public void ShouldHandleException() { //Arrange var sut = new CustomExceptionHandler(); var exception = new Exception("Hello World"); var catchblock = new ExceptionContextCatchBlock("webpi", true, false); var configuration = new HttpConfiguration(); var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/api/test"); request.SetConfiguration(configuration); var exceptionContext = new ExceptionContext(exception, catchblock, request); var context = new ExceptionHandlerContext(exceptionContext); Assert.IsNull(context.Result); //Act sut.Handle(context); //Assert Assert.IsNotNull(context.Result); }
internal static async Task <bool> CopyErrorResponseAsync(ExceptionContextCatchBlock catchBlock, HttpContextBase httpContextBase, HttpRequestMessage request, HttpResponseMessage response, Exception exception, IExceptionLogger exceptionLogger, IExceptionHandler exceptionHandler, CancellationToken cancellationToken) { Contract.Assert(httpContextBase != null); Contract.Assert(httpContextBase.Response != null); Contract.Assert(request != null); Contract.Assert(exception != null); Contract.Assert(catchBlock != null); Contract.Assert(catchBlock.CallsHandler); HttpResponseBase httpResponseBase = httpContextBase.Response; HttpResponseMessage errorResponse = null; HttpResponseException responseException = exception as HttpResponseException; // Ensure all headers and content are cleared to eliminate any partial results. ClearContentAndHeaders(httpResponseBase); // If the exception we are handling is HttpResponseException, // that becomes the error response. if (responseException != null) { errorResponse = responseException.Response; } else { ExceptionContext exceptionContext = new ExceptionContext(exception, catchBlock, request) { Response = response }; await exceptionLogger.LogAsync(exceptionContext, cancellationToken); errorResponse = await exceptionHandler.HandleAsync(exceptionContext, cancellationToken); if (errorResponse == null) { return(false); } } Contract.Assert(errorResponse != null); if (!await CopyResponseStatusAndHeadersAsync(httpContextBase, request, errorResponse, exceptionLogger, cancellationToken)) { // Don't rethrow the original exception unless explicitly requested to do so. In this case, the // exception handler indicated it wanted to handle the exception; it simply failed create a stable // response to send. return(true); } // The error response may return a null content if content negotiation // fails to find a formatter, or this may be an HttpResponseException without // content. In either case, cleanup and return a completed task. if (errorResponse.Content == null) { errorResponse.Dispose(); return(true); } CopyHeaders(errorResponse.Content.Headers, httpContextBase); await WriteErrorResponseContentAsync(httpResponseBase, request, errorResponse, cancellationToken, exceptionLogger); return(true); }
internal static async Task <bool> CopyErrorResponseAsync(ExceptionContextCatchBlock catchBlock, HttpContextBase httpContextBase, HttpRequestMessage request, HttpResponseMessage response, Exception exception, CancellationToken cancellationToken, IExceptionLogger exceptionLogger, IExceptionHandler exceptionHandler) { Contract.Assert(httpContextBase != null); Contract.Assert(httpContextBase.Response != null); Contract.Assert(request != null); Contract.Assert(exception != null); HttpResponseBase httpResponseBase = httpContextBase.Response; HttpResponseMessage errorResponse = null; HttpResponseException responseException = exception as HttpResponseException; // Ensure all headers and content are cleared to eliminate any partial results. ClearContentAndHeaders(httpResponseBase); // If the exception we are handling is HttpResponseException, // that becomes the error response. if (responseException != null) { errorResponse = responseException.Response; } else { ExceptionContext exceptionContext = new ExceptionContext(exception, catchBlock, request) { Response = response }; await exceptionLogger.LogAsync(exceptionContext, canBeHandled : true, cancellationToken : cancellationToken); errorResponse = await exceptionHandler.HandleAsync(exceptionContext, cancellationToken); if (errorResponse == null) { return(false); } } Contract.Assert(errorResponse != null); CopyResponseStatusAndHeaders(httpContextBase, errorResponse); // The error response may return a null content if content negotiation // fails to find a formatter, or this may be an HttpResponseException without // content. In either case, cleanup and return a completed task. if (errorResponse.Content == null) { errorResponse.Dispose(); return(true); } // Copy the headers from the newly generated HttpResponseMessage. // We must ask the content for its content length because Content-Length // is lazily computed and added to the headers. var unused = errorResponse.Content.Headers.ContentLength; CopyHeaders(errorResponse.Content.Headers, httpContextBase); await WriteErrorResponseContentAsync(httpResponseBase, request, errorResponse, cancellationToken, exceptionLogger); return(true); }