Exemple #1
0
        public async Task OnExceptionWritesAnErrorLogEntry()
        {
            var mockActionDescriptor = new Mock <HttpActionDescriptor>();
            var mockLogger           = new Mock <ILogger>();
            var exception            = new InvalidOperationException("One cannot simply walk into Mordor");
            var errorConfiguration   = new ErrorHandlingConfiguration();
            var httpConfiguration    = new HttpConfiguration();
            var routeData            = new HttpRouteData(new HttpRoute());
            var request = new HttpRequestMessage(HttpMethod.Get, "http://api.someservice.com/collection/thing");
            var controllerDescriptor = new HttpControllerDescriptor {
                Configuration = httpConfiguration, ControllerName = "generic"
            };
            var controllerContext = new HttpControllerContext(httpConfiguration, routeData, request)
            {
                ControllerDescriptor = controllerDescriptor
            };
            var actionContext = new HttpActionContext(controllerContext, mockActionDescriptor.Object);
            var errorContext  = new HttpActionExecutedContext(actionContext, exception);

            mockLogger.Setup(logger => logger.ForContext(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>())).Returns(mockLogger.Object);
            mockActionDescriptor.SetupGet(descriptor => descriptor.ActionName).Returns("someAction");

            request.SetConfiguration(httpConfiguration);
            request.SetRouteData(routeData);
            request.Headers.TryAddWithoutValidation(HttpHeaders.CorrelationId, "Not-A-Real-Value");

            var exceptionFilter = new GlobalExceptionFilter(errorConfiguration, mockLogger.Object);
            await exceptionFilter.OnExceptionAsync(errorContext, CancellationToken.None);

            mockLogger.Verify(logger => logger.Error(It.Is <Exception>(ex => ex == exception), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>()), Times.Once, "An error log entry should have been written");
        }
        /// <summary>
        ///   Initializes a new instance of the <see cref="GlobalExceptionFilter"/> class.
        /// </summary>
        ///
        /// <param name="configuration">The configuration to use for error handling decisions.</param>
        /// <param name="log">The log instance to be used for capturing information around observed exceptions.</param>
        ///
        public GlobalExceptionFilter(ErrorHandlingConfiguration configuration,
                                     ILogger log)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            if (log == null)
            {
                throw new ArgumentNullException(nameof(log));
            }


            this.Configuration = configuration;
            this.Log           = log;
        }
Exemple #3
0
        public async Task OnExceptionSetsTheResultWithExceptionContentWhenEnabled()
        {
            var mockActionDescriptor = new Mock <HttpActionDescriptor>();
            var mockLogger           = new Mock <ILogger>();
            var exception            = new InvalidOperationException("One cannot simply walk into Mordor");
            var errorConfiguration   = new ErrorHandlingConfiguration {
                ExceptionDetailsEnabled = true
            };
            var httpConfiguration    = new HttpConfiguration();
            var routeData            = new HttpRouteData(new HttpRoute());
            var request              = new HttpRequestMessage(HttpMethod.Get, "http://api.someservice.com/collection/thing");
            var controllerDescriptor = new HttpControllerDescriptor {
                Configuration = httpConfiguration, ControllerName = "generic"
            };
            var controllerContext = new HttpControllerContext(httpConfiguration, routeData, request)
            {
                ControllerDescriptor = controllerDescriptor
            };
            var actionContext = new HttpActionContext(controllerContext, mockActionDescriptor.Object);
            var errorContext  = new HttpActionExecutedContext(actionContext, exception);

            mockLogger.Setup(logger => logger.ForContext(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>())).Returns(mockLogger.Object);
            mockActionDescriptor.SetupGet(descriptor => descriptor.ActionName).Returns("someAction");

            request.SetConfiguration(httpConfiguration);
            request.SetRouteData(routeData);
            request.Headers.TryAddWithoutValidation(HttpHeaders.CorrelationId, "Not-A-Real-Value");

            var exceptionFilter = new GlobalExceptionFilter(errorConfiguration, mockLogger.Object);
            await exceptionFilter.OnExceptionAsync(errorContext, CancellationToken.None);

            errorContext.Response.Should().NotBeNull("because the response should have been set");
            errorContext.Response.StatusCode.Should().Be(HttpStatusCode.InternalServerError, "because an exception result should be set");
            errorContext.Response.ReasonPhrase.Should().NotContain(exception.ToString(), "because exception details should not appear as the reason");
            errorContext.Response.Content.Should().NotBeNull("because body content should have been set");

            var exceptionContent = await errorContext.Response.Content.ReadAsAsync <Exception>();

            exceptionContent.Message.Should().Be(exception.Message, "because the exception should have been used as the content");
            exceptionContent.StackTrace.Should().Be(exception.StackTrace, "because the exception should have been used as the content");
        }
Exemple #4
0
        public async Task ExceptionHeaderDoesNotContainUnsafeCharacters()
        {
            var mockActionDescriptor = new Mock <HttpActionDescriptor>();
            var mockLogger           = new Mock <ILogger>();
            var exception            = new InvalidOperationException("One cannot simply walk into Mordor");
            var errorConfiguration   = new ErrorHandlingConfiguration {
                ExceptionDetailsEnabled = true
            };
            var httpConfiguration    = new HttpConfiguration();
            var routeData            = new HttpRouteData(new HttpRoute());
            var request              = new HttpRequestMessage(HttpMethod.Get, "http://api.someservice.com/collection/thing");
            var controllerDescriptor = new HttpControllerDescriptor {
                Configuration = httpConfiguration, ControllerName = "generic"
            };
            var controllerContext = new HttpControllerContext(httpConfiguration, routeData, request)
            {
                ControllerDescriptor = controllerDescriptor
            };
            var actionContext = new HttpActionContext(controllerContext, mockActionDescriptor.Object);
            var errorContext  = new HttpActionExecutedContext(actionContext, exception);

            mockLogger.Setup(logger => logger.ForContext(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>())).Returns(mockLogger.Object);
            mockActionDescriptor.SetupGet(descriptor => descriptor.ActionName).Returns("someAction");

            request.SetConfiguration(httpConfiguration);
            request.SetRouteData(routeData);
            request.Headers.TryAddWithoutValidation(HttpHeaders.CorrelationId, "Not-A-Real-Value");

            var exceptionFilter = new GlobalExceptionFilter(errorConfiguration, mockLogger.Object);
            await exceptionFilter.OnExceptionAsync(errorContext, CancellationToken.None);

            errorContext.Response.Should().NotBeNull("because the response should have been set");

            IEnumerable <string> headers;

            errorContext.Response.Headers.TryGetValues(HttpHeaders.ExceptionDetails, out headers).Should().BeTrue("because the exception details header should have been set");
            headers.Count().Should().Be(1, "because a single exception detail header should exist");
            headers.First().Should().NotContain(Environment.NewLine, "because new lines are not allowed in header values");
        }