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));
 }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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
     }));
 }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 10
0
        public void HttpControllerHandlerStreamContent_IsSpecifiedValue()
        {
            // Act
            ExceptionContextCatchBlock catchBlock = WebHostExceptionCatchBlocks.HttpControllerHandlerStreamContent;

            // Assert
            ExceptionContextCatchBlock expected =
                new ExceptionContextCatchBlock("HttpControllerHandler.StreamContent", isTopLevel: true);

            AssertEqual(expected, catchBlock);
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 15
0
        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);
        }
Ejemplo n.º 19
0
        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();
        }
Ejemplo n.º 20
0
        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));
        }
Ejemplo n.º 21
0
        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);
        }