Adding a pattern for returning 'unhandled' exception information via
middleware. This should be used where posssible instead of throwing an exception and catching in a test, as that only works in memory.
This commit is contained in:
parent
1a617eb533
commit
6390bad0d3
|
|
@ -21,12 +21,16 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
var expectedMessage = "No service for type 'ActivatorWebSite.CannotBeActivatedController+FakeType' " +
|
||||
"has been registered.";
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => client.GetAsync("http://localhost/CannotBeActivated/Index"));
|
||||
Assert.Equal(expectedMessage, ex.Message);
|
||||
var response = await client.GetAsync("http://localhost/CannotBeActivated/Index");
|
||||
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidOperationException).FullName, exception.ExceptionType);
|
||||
Assert.Equal(expectedMessage, exception.ExceptionMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -162,9 +166,11 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
"has been registered.";
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(
|
||||
() => client.GetAsync("http://localhost/View/ConsumeCannotBeActivatedComponent"));
|
||||
Assert.Equal(expectedMessage, ex.Message);
|
||||
var response = await client.GetAsync("http://localhost/View/ConsumeCannotBeActivatedComponent");
|
||||
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidOperationException).FullName, exception.ExceptionType);
|
||||
Assert.Equal(expectedMessage, exception.ExceptionMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -100,9 +100,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
request.Content = new FormUrlEncodedContent(nameValueCollection);
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => client.SendAsync(request));
|
||||
Assert.Equal("The anti-forgery token could not be decrypted.", ex.Message);
|
||||
// Act
|
||||
var response = await client.SendAsync(request);
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal("The anti-forgery token could not be decrypted.", exception.ExceptionMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -127,9 +130,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
request.Content = new FormUrlEncodedContent(nameValueCollection);
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => client.SendAsync(request));
|
||||
Assert.Equal("The anti-forgery token could not be decrypted.", ex.Message);
|
||||
// Act
|
||||
var response = await client.SendAsync(request);
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal("The anti-forgery token could not be decrypted.", exception.ExceptionMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -162,9 +168,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
request.Content = new FormUrlEncodedContent(nameValueCollection);
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => client.SendAsync(request));
|
||||
Assert.Equal("The anti-forgery cookie token and form field token do not match.", ex.Message);
|
||||
// Act
|
||||
var response = await client.SendAsync(request);
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal("The anti-forgery cookie token and form field token do not match.", exception.ExceptionMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -189,9 +198,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
request.Content = new FormUrlEncodedContent(nameValueCollection);
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => client.SendAsync(request));
|
||||
Assert.Equal("The required anti-forgery cookie \"__RequestVerificationToken\" is not present.", ex.Message);
|
||||
// Act
|
||||
var response = await client.SendAsync(request);
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal("The required anti-forgery cookie \"__RequestVerificationToken\" is not present.", exception.ExceptionMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -214,10 +226,13 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
request.Content = new FormUrlEncodedContent(nameValueCollection);
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => client.SendAsync(request));
|
||||
// Act
|
||||
var response = await client.SendAsync(request);
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal("The required anti-forgery form field \"__RequestVerificationToken\" is not present.",
|
||||
ex.Message);
|
||||
exception.ExceptionMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Information about an exception that occured on the server side of a functional
|
||||
/// test.
|
||||
/// </summary>
|
||||
public class ExceptionInfo
|
||||
{
|
||||
public string ExceptionMessage { get; set; }
|
||||
|
||||
public string ExceptionType { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -124,8 +124,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var client = server.CreateClient();
|
||||
var url = "http://localhost/RandomNumber/GetAuthorizedRandomNumber";
|
||||
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => client.GetAsync(url));
|
||||
// Act
|
||||
var response = await client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidOperationException).FullName, exception.ExceptionType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -152,8 +156,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var client = server.CreateClient();
|
||||
var url = "http://localhost/RandomNumber/GetHalfOfModifiedRandomNumber?randomNumber=3";
|
||||
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => client.GetAsync(url));
|
||||
// Act
|
||||
var response = await client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidOperationException).FullName, exception.ExceptionType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -465,9 +473,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<InvalidProgramException>(
|
||||
() => client.GetAsync("http://localhost/Home/ThrowingResultFilter"));
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/Home/ThrowingResultFilter");
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidProgramException).FullName, exception.ExceptionType);
|
||||
}
|
||||
|
||||
// Action Filter throws.
|
||||
|
|
@ -496,9 +507,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<InvalidProgramException>(
|
||||
() => client.GetAsync("http://localhost/Home/ThrowingAuthorizationFilter"));
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/Home/ThrowingAuthorizationFilter");
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidProgramException).FullName, exception.ExceptionType);
|
||||
}
|
||||
|
||||
// Exception Filter throws.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNet.Mvc.TestConfiguration;
|
||||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||
{
|
||||
public static class HttpResponseMessageExceptions
|
||||
{
|
||||
public static ExceptionInfo GetServerException(this HttpResponseMessage response)
|
||||
{
|
||||
if (response.StatusCode != HttpStatusCode.InternalServerError)
|
||||
{
|
||||
throw new AssertActualExpectedException(
|
||||
HttpStatusCode.InternalServerError,
|
||||
response.StatusCode,
|
||||
"A server-side exception should be returned as a 500.");
|
||||
}
|
||||
|
||||
var headers = response.Headers;
|
||||
|
||||
IEnumerable<string> exceptionMessageHeader;
|
||||
IEnumerable<string> exceptionTypeHeader;
|
||||
if (!headers.TryGetValues(ErrorReporterMiddleware.ExceptionMessageHeader, out exceptionMessageHeader))
|
||||
{
|
||||
throw new XunitException(
|
||||
"No value for the '" + ErrorReporterMiddleware.ExceptionMessageHeader + "' header.");
|
||||
}
|
||||
|
||||
if (!headers.TryGetValues(ErrorReporterMiddleware.ExceptionTypeHeader, out exceptionTypeHeader))
|
||||
{
|
||||
throw new XunitException(
|
||||
"No value for the '" + ErrorReporterMiddleware.ExceptionTypeHeader + "' header.");
|
||||
}
|
||||
|
||||
return new ExceptionInfo()
|
||||
{
|
||||
ExceptionMessage = Assert.Single(exceptionMessageHeader),
|
||||
ExceptionType = Assert.Single(exceptionTypeHeader),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -42,15 +42,15 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(
|
||||
() => client.GetAsync("http://localhost/area-withoutexists/Users")
|
||||
);
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/area-withoutexists/Users");
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal("The view 'Index' was not found." +
|
||||
" The following locations were searched:\r\n/Areas/Users/Views/Home/Index.cshtml\r\n" +
|
||||
"/Areas/Users/Views/Shared/Index.cshtml\r\n/Views/Shared/Index.cshtml.",
|
||||
ex.Message);
|
||||
" The following locations were searched:__/Areas/Users/Views/Home/Index.cshtml__" +
|
||||
"/Areas/Users/Views/Shared/Index.cshtml__/Views/Shared/Index.cshtml.",
|
||||
exception.ExceptionMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -128,12 +128,15 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||
client.GetAsync("http://localhost/FromAttributes/FromBodyParametersThrows"));
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/FromAttributes/FromBodyParametersThrows");
|
||||
|
||||
Assert.Equal("More than one parameter and/or property is bound to the HTTP request's content.",
|
||||
ex.Message);
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidOperationException).FullName, exception.ExceptionType);
|
||||
Assert.Equal(
|
||||
"More than one parameter and/or property is bound to the HTTP request's content.",
|
||||
exception.ExceptionMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -143,12 +146,15 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||
client.GetAsync("http://localhost/FromAttributes/FromBodyParameterAndPropertyThrows"));
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/FromAttributes/FromBodyParameterAndPropertyThrows");
|
||||
|
||||
Assert.Equal("More than one parameter and/or property is bound to the HTTP request's content.",
|
||||
ex.Message);
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidOperationException).FullName, exception.ExceptionType);
|
||||
Assert.Equal(
|
||||
"More than one parameter and/or property is bound to the HTTP request's content.",
|
||||
exception.ExceptionMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -158,12 +164,15 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||
client.GetAsync("http://localhost/FromAttributes/FormAndBody_AsParameters_Throws"));
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/FromAttributes/FormAndBody_AsParameters_Throws");
|
||||
|
||||
Assert.Equal("More than one parameter and/or property is bound to the HTTP request's content.",
|
||||
ex.Message);
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidOperationException).FullName, exception.ExceptionType);
|
||||
Assert.Equal(
|
||||
"More than one parameter and/or property is bound to the HTTP request's content.",
|
||||
exception.ExceptionMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -173,12 +182,15 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||
client.GetAsync("http://localhost/FromAttributes/FormAndBody_Throws"));
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/FromAttributes/FormAndBody_Throws");
|
||||
|
||||
Assert.Equal("More than one parameter and/or property is bound to the HTTP request's content.",
|
||||
ex.Message);
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidOperationException).FullName, exception.ExceptionType);
|
||||
Assert.Equal(
|
||||
"More than one parameter and/or property is bound to the HTTP request's content.",
|
||||
exception.ExceptionMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -930,13 +942,18 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var client = server.CreateClient();
|
||||
Expression<Func<User, object>> expression = model => model.Address.Country;
|
||||
|
||||
var expected = string.Format(
|
||||
"The passed expression of expression node type '{0}' is invalid." +
|
||||
" Only simple member access expressions for model properties are supported.",
|
||||
expression.Body.NodeType);
|
||||
|
||||
// Act
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||
client.GetAsync("http://localhost/TryUpdateModel/GetUserAsync_WithChainedProperties?id=123"));
|
||||
Assert.Equal(string.Format("The passed expression of expression node type '{0}' is invalid." +
|
||||
" Only simple member access expressions for model properties are supported.",
|
||||
expression.Body.NodeType),
|
||||
ex.Message);
|
||||
var response = await client.GetAsync("http://localhost/TryUpdateModel/GetUserAsync_WithChainedProperties?id=123");
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidOperationException).FullName, exception.ExceptionType);
|
||||
Assert.Equal(expected, exception.ExceptionMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -925,11 +925,11 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var expectedMessage = "The supplied route name 'DuplicateRoute' is ambiguous and matched more than one route.";
|
||||
|
||||
// Act
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () =>
|
||||
await client.GetAsync(url));
|
||||
var response = await client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedMessage, ex.Message);
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(expectedMessage, exception.ExceptionMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -577,8 +577,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
var request = new HttpRequestMessage(new HttpMethod("POST"), "http://localhost/api/Admin/Test?name=mario");
|
||||
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<AmbiguousActionException>(async () => await client.SendAsync(request));
|
||||
// Act
|
||||
var response = await client.SendAsync(request);
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(AmbiguousActionException).FullName, exception.ExceptionType);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
|
|||
|
|
@ -50,9 +50,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
"<SampleInt>" + sampleInputInt.ToString() + "</SampleInt></DummyClass>";
|
||||
var content = new StringContent(input, Encoding.UTF8, "application/xml");
|
||||
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(
|
||||
async () => await client.PostAsync("http://localhost/Home/Index", content));
|
||||
// Act
|
||||
var response = await client.PostAsync("http://localhost/Home/Index", content);
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidOperationException).FullName, exception.ExceptionType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,9 @@ namespace ActivatorWebSite
|
|||
services.AddScoped<ViewService, ViewService>();
|
||||
});
|
||||
|
||||
// Used to report exceptions that MVC doesn't handle
|
||||
app.UseErrorReporter();
|
||||
|
||||
// Add MVC to the request pipeline
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ namespace AntiForgeryWebSite
|
|||
services.AddMvc(configuration);
|
||||
});
|
||||
|
||||
app.UseErrorReporter();
|
||||
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute("ActionAsMethod", "{controller}/{action}",
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ namespace FiltersWebSite
|
|||
});
|
||||
});
|
||||
|
||||
app.UseErrorReporter();
|
||||
|
||||
app.UseMvc();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
|
|
@ -11,8 +10,6 @@ namespace InlineConstraints
|
|||
{
|
||||
public class Startup
|
||||
{
|
||||
public Action<IRouteBuilder> RouteCollectionProvider { get; set; }
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
var configuration = app.GetTestConfiguration();
|
||||
|
|
@ -22,6 +19,8 @@ namespace InlineConstraints
|
|||
services.AddMvc(configuration);
|
||||
});
|
||||
|
||||
app.UseErrorReporter();
|
||||
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute("StoreId",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.TestConfiguration;
|
||||
using Microsoft.Framework.ConfigurationModel;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
|
|
@ -18,5 +19,10 @@ namespace Microsoft.AspNet.Builder
|
|||
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public static IApplicationBuilder UseErrorReporter(this IApplicationBuilder app)
|
||||
{
|
||||
return app.Use(next => new ErrorReporterMiddleware(next).Invoke);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.TestConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// A middleware that reports errors via header values. Useful for tests that want to verify
|
||||
/// an exception that goes unhandled by the MVC part of the stack.
|
||||
/// </summary>
|
||||
public class ErrorReporterMiddleware
|
||||
{
|
||||
public static readonly string ExceptionMessageHeader = "ExceptionMessage";
|
||||
public static readonly string ExceptionTypeHeader = "ExceptionType";
|
||||
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
public ErrorReporterMiddleware(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _next(context);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (context.Response.HeadersSent)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.StatusCode = 500;
|
||||
|
||||
var escapedMessage = exception.Message.Replace('\r', '_').Replace('\n', '_');
|
||||
|
||||
context.Response.Headers.Add(ExceptionTypeHeader, new string[] { exception.GetType().FullName });
|
||||
context.Response.Headers.Add(ExceptionMessageHeader, new string[] { escapedMessage });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,6 +30,8 @@ namespace ModelBindingWebSite
|
|||
services.AddSingleton<ITestService, TestService>();
|
||||
});
|
||||
|
||||
app.UseErrorReporter();
|
||||
|
||||
// Add MVC to the request pipeline
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ namespace RoutingWebSite
|
|||
services.AddScoped<TestResponseGenerator>();
|
||||
});
|
||||
|
||||
app.UseErrorReporter();
|
||||
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute("areaRoute",
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ namespace WebApiCompatShimWebSite
|
|||
services.AddWebApiConventions();
|
||||
});
|
||||
|
||||
app.UseErrorReporter();
|
||||
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
// This route can't access any of our webapi controllers
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ namespace XmlSerializerWebSite
|
|||
});
|
||||
});
|
||||
|
||||
app.UseErrorReporter();
|
||||
|
||||
// Add MVC to the request pipeline
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue