Best way to handle global exception in Asp.Net Core Web API
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.
- Consistent Error Handling
- CREATE EXCEPTION CLASS
- THROWING RELEVANT EXCEPTIONS FROM CODE
- CREATE APPLICATION EXCEPTION MIDDLEWARE AND EXCEPTION HANDLER
- Wrapping Up
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
, 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.500 Internal Server Error
- 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 :)
List questions & answers
-
1. What is global error handling in Asp.Net Core Web API?This method is called whenever an error is thrown somewhere in the application. The error is passed as a parameter and can be processed further inside the method. In our case, a dialog is opened where the error message should be displayed and the error is logged to the browser console, Maybe I also can write into a file text or database.
-
2. How do you handle errors in .NET Core API?
-
3. Should I use global or local errors handling in Asp.Net Core Web API?
COMMENT