Search code examples
asp.net-coreexceptionasp.net-core-middleware

Get exception in Middleware


I want to create an AspNetCore Middleware (old IHttpModule), which should capture exceptions (later on save them or something similar)

However, i don't know how to capture the Exception inside Middleware, although the HttpStatusCode is 500

Here is what i have:

// Middleware
internal class ExceptionMiddleware
{
    private readonly RequestDelegate _next;

    public ExceptionMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next.Invoke(context);
        }
        catch (Exception ex)
        {
            // never gets here
        }

        // 500
        HttpStatusCode statusCode = (HttpStatusCode)context.Response.StatusCode;

        // how to get error message?
    }
}

// Middleware Extension method
public static class ExceptionMiddlewareExtensions
{
    public static IApplicationBuilder UseExceptionMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<ExceptionMiddleware>();
    }
}

// Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseExceptionMiddleware();

    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

I trigger the exception like this:

public IActionResult Index()
{
    var test = 0;
    var a = 100 / test;

    return View();
}

Solution

  • You correctly use try-catch in middleware.

    But your problem is that you also register the ExceptionHandler middleware (app.UseExceptionHandler). This middleware catches all unhandled exceptions and set 500 status code if could handle it.


    As a possible solution consider to swap the order of middlewares, so your middleware will be the first one that catches the exceptions occurred further in the pipeline:

    app.UseExceptionHandler("/Home/Error");
    app.UseExceptionMiddleware();