X

Best way to handle global exception in Asp.Net Core Web API

Ankit Kashyap Sep 10 2021 344
In this article, I will discuss the basic ways to help you how to handle global errors in Asp.net Core Web API. Why do we need to handle global and not local? In web API, exceptions have many types and they may be not the same as a web application.

Let’s get started

  • It is common to see that popular HTTP error status codes such as 400 Bad Request, 401 Unauthorized, 404 Not found, 500 Internal Server Error, and so on return different HTTP Response formats. In fact, even for a single status code, the response could be plain text or JSON. This makes the error parsing at the client-side is very difficult since the response could vary based on the status code and sometimes even for the same status code.
  • In addition to this, the error handling logic is scattered across all the Controllers. That makes it tricky to change a response object since we would need to update every controller.

Below pseudo-code is an example controller with the inconsistent response for different error codes.

Consistent Error Handling

Taking a leaf out of JSON:API specification and JsonApiDotNetCore, I tried to implement a consistent way of handling errors in ASP.NET Core.

CREATE EXCEPTION CLASS

To solve the next part of our problem, we start by creating an Exception classes for every error status code.

As you can see in the above code, we have a separate exception class for every error status code that we expect our application to return.

THROWING RELEVANT EXCEPTIONS FROM CODE

Next, instead of returning HTTP error status code from the Controller, we throw a relevant exception.

If you are following Clean Architecture or Domain-Driven Design (DDD) in your project, then the Controllers are usually thin. With DDD, the business logic stays within the Domain. QueryHandler and CommandHandler act as an interface between the Controller and Domain/ Repository. In addition to this, the cross-cutting concerns such a validation, authorization etc., are handled through Middeware or ActionFilter, keeping the Controllers lean.

This allows us to throw a relevant exception from different parts of our code. The below pseudo-code demonstrates how we can keep the error handling outside the Controllers by throwing the Exceptions.

Accordingly, we can return our custom errors from any layer of our application.

CREATE APPLICATION EXCEPTION MIDDLEWARE AND EXCEPTION HANDLER

Next, we create ApplicationExceptionMiddleware and ExceptionHandler classes to handle all the exceptions that are thrown from the different parts of the code. The ExceptionHandler is one single place where we handle all our HTTP error status, and we return the error response to the client through ApplicationExceptionMiddleware.

Last but not the least, we need to register ExceptionHandler and ApplicationExceptionMiddleware in Startup.

Wrapping Up

In this post, I have presented a clean way to achieve consistent exception handling for your ASP.NET Core Rest APIs. I hope you enjoy reading this post and it was helpful in some way.

Happy Learning :)