Add an option to allow 404 responses from ExceptionHandlers (#26567)
This commit is contained in:
parent
d5b5f08a4f
commit
8555002772
|
|
@ -132,7 +132,7 @@ namespace Microsoft.AspNetCore.Diagnostics
|
|||
|
||||
await _options.ExceptionHandler(context);
|
||||
|
||||
if (context.Response.StatusCode != StatusCodes.Status404NotFound)
|
||||
if (context.Response.StatusCode != StatusCodes.Status404NotFound || _options.AllowStatusCode404Response)
|
||||
{
|
||||
if (_diagnosticListener.IsEnabled() && _diagnosticListener.IsEnabled("Microsoft.AspNetCore.Diagnostics.HandledException"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,5 +22,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// explicitly provided, the subsequent middleware pipeline will be used by default.
|
||||
/// </summary>
|
||||
public RequestDelegate ExceptionHandler { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This value controls whether the <see cref="ExceptionHandlerMiddleware" /> should
|
||||
/// consider a response with a 404 status code to be a valid result of executing the
|
||||
/// <see cref="ExceptionHandler"/>. The default value is false and the middleware will
|
||||
/// consider 404 status codes to be an error on the server and will therefore rethrow
|
||||
/// the original exception.
|
||||
/// </summary>
|
||||
public bool AllowStatusCode404Response { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -542,5 +542,59 @@ namespace Microsoft.AspNetCore.Diagnostics
|
|||
&& w.EventId == 4
|
||||
&& w.Message == "No exception handler was found, rethrowing original exception.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExceptionHandler_CanReturn404Responses_WhenAllowed()
|
||||
{
|
||||
var sink = new TestSink(TestSink.EnableWithTypeName<ExceptionHandlerMiddleware>);
|
||||
var loggerFactory = new TestLoggerFactory(sink, enabled: true);
|
||||
|
||||
using var host = new HostBuilder()
|
||||
.ConfigureWebHost(webHostBuilder =>
|
||||
{
|
||||
webHostBuilder
|
||||
.UseTestServer()
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddSingleton<ILoggerFactory>(loggerFactory);
|
||||
services.Configure<ExceptionHandlerOptions>(options =>
|
||||
{
|
||||
options.AllowStatusCode404Response = true;
|
||||
options.ExceptionHandler = httpContext =>
|
||||
{
|
||||
httpContext.Response.StatusCode = StatusCodes.Status404NotFound;
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
});
|
||||
})
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseExceptionHandler();
|
||||
|
||||
app.Map("/throw", (innerAppBuilder) =>
|
||||
{
|
||||
innerAppBuilder.Run(httpContext =>
|
||||
{
|
||||
throw new InvalidOperationException("Something bad happened.");
|
||||
});
|
||||
});
|
||||
});
|
||||
}).Build();
|
||||
|
||||
await host.StartAsync();
|
||||
|
||||
using (var server = host.GetTestServer())
|
||||
{
|
||||
var client = server.CreateClient();
|
||||
var response = await client.GetAsync("throw");
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
Assert.Equal(string.Empty, await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
Assert.DoesNotContain(sink.Writes, w =>
|
||||
w.LogLevel == LogLevel.Warning
|
||||
&& w.EventId == 4
|
||||
&& w.Message == "No exception handler was found, rethrowing original exception.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue