15

I have in my startup.cs file:

if (env.IsDevelopment()) {               
    app.UseExceptionHandler("/api/error/error-local-development");               
}
else {             
    app.UseExceptionHandler("/api/error/error");
}

But when throw new Exception() in a controller action, the Error controller Methods are never called.

[Route("api/error")]
[ApiController]
[ApiExplorerSettings(IgnoreApi = true)]
public class ErrorController : OwnBaseController
{
    public ErrorController(IApplicationUserService applicationUserService, ILogger<ErrorController> logger, IDiagnosticContext diagnosticContext) : base(applicationUserService, logger, diagnosticContext)
    {
    }

    [Route("error")]
    public IActionResult Error()
    {
        return Problem(); 
    }

    [Route("error-local-development")]
    public IActionResult ErrorLocalDevelopment([FromServices] IWebHostEnvironment webHostEnvironment)
    {
       var context = HttpContext.Features.Get<IExceptionHandlerFeature>();
       return Problem(
            detail: context.Error.StackTrace,
            title: context.Error.Message);
    }
}

Why is this not working?

6
  • What will happen then? I mean is the app crashes or do the exception appears in the log? or xyz? Commented Feb 26, 2021 at 14:34
  • In debug modus i see on the manual "throw exception" serilog logging "an exception of type xx occured in xxx.dll but was not handled in user code", it then jumps to the lines line of my testmethod of my test controller and returns a 500. Commented Feb 26, 2021 at 14:40
  • Where did you put the UseExceptionHandler calls before or after the UseRouting and UseEndpoints? Commented Feb 26, 2021 at 14:48
  • after app.UseRouting() Commented Feb 26, 2021 at 14:57
  • 3
    Please try to register them before. These could be the very first method calls in the Configure. Commented Feb 26, 2021 at 14:59

4 Answers 4

19

It might seem strange but ordering does matter.

UseExceptionHandler and UseRouting are both registering middlewares under the hood.

The firstly registered will be the outer most middleware. So, if one of the inners throws an exception the outer can catch and handle it.

middleware ordering Source

MSDN has some warnings about this, for example:

If an endpoint within the app is specified, create an MVC view or Razor page for the endpoint. Ensure UseStatusCodePagesWithReExecute is placed before UseRouting so the request can be rerouted to the status page.

UseExceptionHandler is the first middleware component added to the pipeline. Therefore, the Exception Handler Middleware catches any exceptions that occur in later calls.

Sign up to request clarification or add additional context in comments.

5 Comments

I was really hoping this simple solution would have fixed my case. My called to UseExceptionHandler is called first, but the unhandled exception still does not call the error handling controller. There must be other causes for this issue.
Hi @MatthewMacFarland, could you please share further details in order to be able to help you? (If needed please create a new question and paste here the link)
Hi @PeterCsala, Certainly. I will put my details together and post them soon.
Hi @PeterCsala, I discovered my problem while getting ready to post details here. I was running in development mode and the call to app.UseExceptionHandler() was only active for when IsDevelopmentMode = false. Silly mistake. Everything works perfectly now.
Hi @MatthewMacFarland it happens to everyone, no worries. I'm glad that you could solve it on your own.
3

It didn't help for me so, I changed this

app.UseExceptionHandler("Home/Error");

to this

app.UseExceptionHandler("/Error");

and aldo added an attribute route on the action

[Route("/Error")]
public IActionResult Error()

Comments

0

For me it was the route name was not the same as the usEexceptionHandler:

I had

[Route("/errors")]
public IActionResult Error()

and in my program.cs:

app.UseExceptionHandler("/error");

both names must be the same for it to work

Comments

0

In my case, I set the exception handler to be called before UseEndpoints. If it comes after UseEndpoints the handler never gets called.

var app = builder.Build();
app.UseCors();
app.UseRouting();
app.UseAuthorization();

// should be called before UseEndpoints else the exception handler wont be called
app.UseExceptionHandler(); 
app.UseEndpoints(endpoints => endpoints.MapControllers());
app.MapControllers();
app.Run();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.