Global Exception Handling in Asp.NET API using Middleware
Why Global Exception Handling?
Error Handling is certainly one of those areas that if you don’t handle it comprehensively, it will make your application prone to unhandled exceptions which creates an inconsistent experience for the consumers of your API.
One way to manage exceptions is to handle them locally on a case by case basis, within each method or routine, however you will have a pile of inconsistent try/catches when your application scales and a lot of holes in it.
The approach that I suggest is to have a global mechanism around your API, which can catch all the “unexpected” exceptions, and provide your consumers with a consistent experience.
Please note this post does not cover request validation and error handling, for that, you can have a look at Fluent Request Validation.
By the way, this topic belongs to the series to set up an Asp.NET API for production use.
- API Route Versioning
- Configuration Management
- Secret Management
- Request Validation
- Global Exception Handling
- URL Rewriting
- Deploy .NET API to Azure App Service
Should I use exceptions to manage application flow ?
In my view, you should generally try to avoid using exceptions to manage application flow (control flow), and here are my reasons:
- Glorified GoTo!? If you like using GoTo in your modern applications, you should use exceptions to manage control flow. Exceptions break the flow, the chain of command and make the flow jump from one point to another abruptly (much like a GoTo statement but at a larger scale). As your code grows in size, this problem will manifest itself even more.
- Exceptions are expensive: Throwing an exception is expensive from the performance stand point, and makes your application performance degrade, if you use them all over the shop to manage your flow.
- Exceptions are for exceptional cases? As long as you can manage the flow of your application with standard flow-control mechanisms, you should leave the exceptions for exceptional cases that you have no control over; cases like Stack Overflow, Out of Memory, etc.
- Code Readability & Maintainability: Which type of code can you read easier? The type that has a logical flow and you can follow the flow by going step by step, or the one which jumps from one point to the other every now and then?
There are also a few ways to implement exception handling in your Asp.NET API.
1. Middleware: Gives you a clean and straightforward global exception handling mechanism injected into your request pipeline.
2. Exception Filter: To be applied at the method, controller and API levels to manage exceptions. It is pretty easy to set up and I will cover it in a separate post.
Exception Handling using Asp.NET 5.0 Middleware
This is very easy to implement and provides a very good error handling coverage around your API. It consists of defining a middleware, and injecting that into your request pipeline.
1. Define the Middleware
Below is how you define your middleware, and here are the steps.
- 1. Process the request in InvokeAsync method
- 2. If it threw an unhandled exception, anywhere in the pipeline, log it
- 3. Inject a user friendly error message into the response
- 4. Send it to the consumer with a 500 status code
That’s all this middleware does. For how I have implemented logging, refer to Asp.NET Monitoring and Logging using NLog.
Configuration, plumbing and troubleshooting your software foundation take a considerable amount of time in your product development. Consider using Pellerex which is a complete foundation for your enterprise software products, providing source-included Identity and Payment functions across UI (React), API (.NET), Pipeline (Azure DevOps) and Infrastructure (Kubernetes).
2. Inject it into Request Pipeline
Next we need to introduce this middleware into our API, by injecting it into the request pipeline.
And here is the extension method I have used to keep it clean.
How are you building your current software today? Build everything from scratch or use a foundation to save on development time, budget and resources? For an enterprise software MVP, which might take 8–12 months with a small team, you might indeed spend 6 months on your foundation. Things like Identity, Payment, Infrastructure, DevOps, etc. they all take time, while contributing not much to your actual product. These features are needed, but they are not your differentiators.
Pellerex does just that. It provides a foundation that save you a lot development time and effort at a fraction of the cost. It gives you source-included Identity, Payment, Infrastructure, and DevOps to build Web, Api and Mobile apps all-integrated and ready-to-go on day 1.
Check out Pellerex and talk to our team today to start building your next enterprise software fast.