1

I created an exception handling middleware according to this example:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseExceptionHandler("/error");
    
    // ...
}

[AllowAnonymous]
[ApiExplorerSettings(IgnoreApi = true)]
[ApiController]
public class ErrorsController : ControllerBase
{
    [Route("error")]
    public IActionResult Error()
    {
        return Problem();
    }
}

Now let's say that I threw the following exception: throw new Exception("BAX");
My exception handling middleware catches this exception and works great. But the problem is that in console I see the following log:

|ERROR|Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware|An unhandled exception has occurred while executing the request.|System.Exception: BAX (stack trace goes here)

Note: I removed stack trace to make it a little bit shorter.

Maybe I should also say that I use NLog for logging. Here is the configuration of it:

<target xsi:
    type = "ColoredConsole" name = "colored_console"
    layout = "|${level:uppercase=true}|${logger}|${message}|${exception:format=tostring}">
</target >

Question

My exception was caught by Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware. It looks like my exception handling middleware didn't handle the exception. Am I right?

My question is why it works so and how can I fix it?

Kirk Larkin
  • 84,915
  • 16
  • 214
  • 203
Boris Makhlin
  • 240
  • 5
  • 11

1 Answers1

1

The duty of app.UseExceptionHandler("errors") is log errors then redirect users to a page in order to show them a proper message.

First of all, when you have app.UseExceptionHandler("errors") it means, ASP.NET Core redirects to a controller named errors and according to your code, it won't work because your Conroller name is Errors and in your code you defined error as its path.

if you don't want Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware to be called, then you have to write your own middleware and log errors there. here is an example of custom middleware to catch all exceptions.

   public class CustomMiddlewareMiddleware
{
    private readonly RequestDelegate _next;

    public CustomMiddlewareMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext httpContext)
    {
        try
        {
            await _next(httpContext);
           
        }
        catch (System.Exception)
        {

            /// log it here and then redirect to spesific path
       
            if (httpContext.Response.StatusCode == 404 && !httpContext.Response.HasStarted)
            {
                httpContext.Request.Path = "/error/404/";
                await _next(httpContext);
            }
        }
      
    }
}
osman Rahimi
  • 1,427
  • 1
  • 11
  • 26
  • Thanks for the answer! In my project I don't have `app.UseExceptionHandler("errors")` -I have `app.UseExceptionHandler("error")`, so because of this it works great. But why to create a middleware instead of exception filter? – Boris Makhlin May 17 '21 at 11:10
  • in your question, you have this ` app.UseExceptionHandler("/error");` and your controller name is `errors`, these are not same – osman Rahimi May 17 '21 at 11:12
  • 1
    `ErrorsController` doesn't have any route. Route `/error` is a route to the action method of this controller. As you can see, there is an action method called `Error` inside of this controller. This action method has the following attribute above: `[Route("error")]` – Boris Makhlin May 17 '21 at 11:15
  • But again, I want to know, why I should use a middleware instead of exception filter in this situation? – Boris Makhlin May 17 '21 at 11:16
  • in your comment you said, how can we avoid calling `Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware`, I thought you might want to have your own middleware. – osman Rahimi May 17 '21 at 11:46