Global Exception Handling in ASPNET Core WEB API

Global Exception Handling in ASP.NET Core WEB API

Exception handling is one of the most important part of any application that needs to addressed and implemented properly. With respect to ASP.NET Core, things have changed and are in better shape to implement exception handling. Implementing exception handling for every action method in API, is quite time consuming and requires extra efforts. So in this post, find out how to implement global exception handling in ASP.NET Core WEB API.

The benefit of implementing global exception handling is that you need to implement in at one place. Any exception occurs in your application will be handled, even when you add new controllers or new methods. That’s quite cool. Isn’t it? Now, let’s see how to implement it.

Global Exception Handling in ASP.NET Core WEB API

There are a couple of ways to implement exception handling globally. You might be aware about introduction of Middlware in ASP.NET Core and ASP.NET Core is shipped with the some in-built middleware components. And one of the in-bulit ASP.NET Core diagnostic middleware is UseExceptionHandler. Read more about Various ASP.NET Core Diagnostics Middleware

UseExceptionHandler can be used to handle exceptions globally. You can get all the details of exception object like Stack Trace, Inner exception and others. And then you can show them on screen. You can easily implement like this.

 options => {
    async context =>
      context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
      context.Response.ContentType = "text/html";
      var ex = context.Features.Get<IExceptionHandlerFeature>();
      if (ex != null)
        var err = $"<h1>Error: {ex.Error.Message}</h1>{ex.Error.StackTrace }";
        await context.Response.WriteAsync(err).ConfigureAwait(false);

You need to put this inside configure() of startup.cs file. Now let’s throw some exception. I am using the default template of ASP.NET Core Web API project. So open ValuesController.cs, modify the Get() method to throw an exception.

// GET api/values
public IEnumerable<string> Get()
    string[] arrRetValues = null;
    if(arrRetValues.Length > 0)
    { }
    return arrRetValues;

Run the application and you should see following. You can also debug it and check in case of exception, it is hitting the app.UseExceptionHandler() code.

UseExceptionHandler() error

This is simple and all good. Another way to implement it using IExceptionFilter and by creating your own custom exception handler. The interface looks like,

namespace Microsoft.AspNetCore.Mvc.Filters
    public interface IExceptionFilter : IFilterMetadata
        void OnException(ExceptionContext context);

As you can see, there is only one method which needs to be implemented. And this method will be invoked whenever there is an unhandled exception. So let’s create a class which implements IExceptionFilter.

public class CustomExceptionFilter : IExceptionFilter
    public void OnException(ExceptionContext context)
        HttpStatusCode status = HttpStatusCode.InternalServerError;
        String message = String.Empty;

        var exceptionType = context.Exception.GetType();
        if (exceptionType == typeof(UnauthorizedAccessException))
            message = "Unauthorized Access";
            status = HttpStatusCode.Unauthorized;
        else if (exceptionType == typeof(NotImplementedException))
            message = "A server error occurred.";
            status = HttpStatusCode.NotImplemented;
        else if (exceptionType == typeof(MyAppException))
            message = context.Exception.ToString();
            status = HttpStatusCode.InternalServerError;
            message = context.Exception.Message;
            status = HttpStatusCode.NotFound;
        HttpResponse response = context.HttpContext.Response;
        response.StatusCode = (int)status;
        response.ContentType = "application/json";
        var err = message + " " + context.Exception.StackTrace;

Here exception type is checked and based on exception type, message and status properties are set. There is also a custom exception type MyAppException (line no. 19) used. To create custom exception, class needs to be inherited from Exception class.

public class MyAppException : Exception
    public MyAppException()
    { }

    public MyAppException(string message)
        : base(message)
    { }

    public MyAppException(string message, Exception innerException)
        : base(message, innerException)
    { }

And finally add our filter using the ConfigureServices method in the Startup class.

public void ConfigureServices(IServiceCollection services)
    // Add framework services.
        config => { 

Now when you run the application and exception occurs, then it will be handled by onException method. And to test custom exception, update Get(int id) method to throw custom exception.

// GET api/values/5
public string Get(int id)
    string sMessage = "test";
    if (sMessage.Length > 0)
        throw new MyAppException("My Custom Exception");
    return sMessage;


So in this post, we learnt about handling exception globally either via built-in middleware or using the built-in exception filter.

Thank you for reading. Keep visiting this blog and share this in your network. Please put your thoughts and feedback in comments section.

PS: If you found this content valuable and want to return the favour, then
Buy Me A Coffee

14 thoughts on “Global Exception Handling in ASP.NET Core WEB API

  1. At the time of Writing

    “`app.UseExceptionHandler()“` I am getting a red squiggle. I don’t know what to import.
    can you help me .

    I code in Visual Studio Code. I am learning by doing things manually. All By Myself. But Doing things Manually is a cumbersome process. Can you please give me series of blog posts or tutorial about this topic.

    It will be a great HELP. TIA

  2. await context.Response.WriteAsync(err).ConfigureAwait(false);

    gives me an error httpResponse does not contain a definition for WriteAsync. What am I missing here


  3. That’s really a great example. I tried to run it but I got 1 problem, It looks like my web api return nothing if I tried to throw any exception.

    The postman said “Could not get any response”. I debugged it, and it already gone to the “OnException”. But the response does not send back.

    Can you help me out ?


  4. this is not working if an exception occurs while serving static files.. its only working for errors in the controller. Can you please help

  5. I can’t seem to be able to my web api to throw exception through AJAX request.
    I get “net::ERR_INCOMPLETE_CHUNKED_ENCODING” in Chrome Console Log.
    I’m not about to catch the error status code and message with jqXHR

    However, if I directly access the api url in the browser, the exception message can be displayed in view.

  6. This is really good, thanks for sharing. Just a quick thought about this: “var err = message + ” ” + context.Exception.StackTrace;”
    You’re returning the full stack trace to the client here. That’s not generally going to be good practice. Depending on the severity of the exception, it might be better to log that to a file instead of including it with your response.
    Also, is this the best practice for calling an async method within a synchronous method? It might be relatively safe in this case, but you can be at risk of deadlock calling async code like this. It might be better to call .Wait() as well (and specify a short timeout as this method call should execute very quickly).

Leave a Reply

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

12 + eighteen =