Global Exception Handling using Middleware in .NET Core

Global Exception Handling using Middleware in NET

Exception handling for some of us is all about using try and catch blocks and throw statements in the application. Most of the time proper analysis or design approach never gets identified for the exception handling. Today we will see how to enable Global Exception Handling using Middleware in .NET Core-based applications like API or MVC apps.

Today in this article, we will cover below aspects,

In our previous article, we already talked about the below aspects in detail which are important while considering proper design around exception handling,

In this article, we will see another preferred approach of using a global middleware component for handling exceptions in the ASP.NET Core application.

Let’s first understand the middleware’s role in the API pipeline. As shown in the below figure each middleware component in the request pipeline is responsible for invoking the next middleware component in the pipeline.

Now let’s use this concept and if we add first middleware as our own exception middleware component shouldn’t it suffice as our global exception handler? The answer is Yes. This component will handle all exceptions happening across API or Business or any other component including other middleware which are part of the application.

Getting started

Create an ASP.NET Core API

Please choose either .NET Core 3.1 or .NET 5 project template.

Global Exception Middleware in NET

Overall creating a middleware component is just a 2-3 steps process.

Adding Middleware component

  • The first step is to add a public class as ExceptionMiddleware.

public class ExceptionMiddleware
    {
        private readonly RequestDelegate _next;

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

        public async Task InvokeAsync(HttpContext httpContext)
        {
            try
            {
                await _next(httpContext);
            }
            catch (Exception ex)
            {
                await HandleGlobalExceptionAsync(httpContext, ex);
            }
        }

        private static Task HandleGlobalExceptionAsync(HttpContext context, Exception exception)
        {
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            return context.Response.WriteAsync(new GlobalErrorDetails()
            {
                StatusCode = context.Response.StatusCode,
                Message = "Something went wrong !Internal Server Error"
            }.ToString());
        }
    }

  • The next step is to create a public static class GlobalExceptionMiddleware

public static class GlobalExceptionMiddleware
    {
        public static void UseGlobalExceptionMiddleware(this IApplicationBuilder app)
        {
            app.UseMiddleware<ExceptionMiddleware>();
        }
    }

  • The last step is to enable this middleware in Startup.cs as shown below.

Middleware Exception Handling NET

Generic Exception Code and Message

Now let’s test controller logic with some exceptions. Error response for most exceptions will be generic as below,

Exception Handling NET using global middleware

Tips:

As a good practice, the above-mentioned logic can be centralized in the form of a library/Nuget package. This library can be shared across any project so that there is uniformity across error handling.

Global Exception Handling in NET

  • Also, try to throw an exception from other layers of your application like the BAL/Domain layer and make only the highest layer of your application swallow it. A throw will keep your stack trace details intact allowing you to log exception details.

Other references :

Using Global Exception Handler for ASP.NET Core exception handler

Logging exceptions in the Global Middleware component

Do you have any comments or ideas or any better suggestions to share?

Please sound off your comments below.

Happy Coding !!

Summary

Today we learned about global exception handling using the middleware approach in .NET Core. Centralize exception handling using the middleware approach brings uniformity across, how exceptions are handled in the applications. Proper exception handling /error handling helps in resolving the business/technical issues and is very critical for business success.



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.



8 thoughts on “Global Exception Handling using Middleware in .NET Core

  1. Might be useful to note that this does not work if the application has an IExceptionFilter setup. The IExceptionFilter will consume the exception before it gets to the middleware and it will not be tracked.

    1. Thanks, Stephen for that note. If any other layer absorbs the exception then the global exception will not have access to those exceptions.
      Also not that IException filters work on Controller/API route layers, it doesn’t catch the exception thrown outside of that like other middleware/module,s etc…. in such cases Global exception will catch all those exceptions if implemented…

  2. Thanks for the article. Just an FYI:

    You have a typo in the static class method: UseGloablExceptionMiddleware(this IApplicationBuilder)

    Global is misspelled.

  3. Thanks, how can we use serilog or other logger along with this.Can other logger work along with it as you overidding the and adding to console?

    1. Hello Mos,
      Thanks for your query. In the sample, however, I have created a new console logger object with an idea of the global logger taking care of logging concerns. But you can inject ILogger from Pipeline configured using Serilog provider and through DI use it in any layer of your application. If interested on how it will work, please check my articles on the same,
      https://thecodebuzz.com/file-logging-in-net-core-2-2-and-net-core-3-0/
      Thanks again.

  4. Thanks for above details .I liked it. The only suggestion would be to explain more in details the logic of actual middleware component.

Leave a Reply

Your email address will not be published. Required fields are marked *