Reputation: 253
I want to show the developer exception page when there is an unhandled exception but I also want to add logging to it. But when I use app.UseDeveloperExceptionPage
together with app.UseExceptionHandler
, only the last one I add works. How can I make the two work together?
Upvotes: 10
Views: 2066
Reputation: 1157
In my case, I wanted to get the developer exception page when the request is sent with the text/html
header to make debugging a bit easier.
SpiritBob's answer worked but it changed the route shown in the developer page to the error handling endpoint
I fixed this by registering the exception handler middleware using a branching request pipeline. Instead of just registering the exception handler like this:
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
else
{
app.UseExceptionHandler("/Error-Development");
}
You change it to this:
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
else
{
app.UseWhen(
context =>
{
RequestHeaders headers = context.Request.GetTypedHeaders();
MediaTypeHeaderValue mediaTypeHeaderValue = new("text/html");
return !headers.Accept.Any(h => h.IsSubsetOf(mediaTypeHeaderValue));
},
applicationBuilder => applicationBuilder.UseExceptionHandler("/Error-Development"));
}
This will use the exception handler middleware unless you include text/html
in the accept header. In which case, it will allow the exception to bubble up to the developer exception page middleware and return a nicely formatted exception page.
Upvotes: 0
Reputation: 2672
You don't need to move your logic to an exception filter.
You can simply re-throw the exception received from the IExceptionHandlerFeature
you used (IExceptionHandlerFeature
/IExceptionHandlerPathFeature
)
For example:
var exceptionFeature = context.Features.Get<IExceptionHandlerFeature>();
throw exceptionFeature.Error;
Then your DeveloperExceptionPage will catch the exception down the pipeline.
Upvotes: 3
Reputation: 32068
The default ExceptionHandler does not work with the DeveloperExceptionPage because it catches the Exception.
What you can do is add an ExceptionFilter, log the Exception and let it be caught by the DeveloperExceptionPage:
public class ExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
Log.Error(context.Exception, $"{context.ActionDescriptor.DisplayName}");
// the important bit here
context.ExceptionHandled = false;
}
}
And then add it to the filters:
services.AddMvc(setup => { /* ... */ setup.Filters.Add<ExceptionFilter>(); });
Upvotes: 4