Introduction
When building modern ASP.NET Core Web APIs, handling errors properly is very important for creating reliable, secure, and user-friendly applications. If exceptions are not handled correctly, they can crash the application, expose sensitive information, or confuse API consumers.
Global Exception Handling in ASP.NET Core Web API provides a centralized way to catch and manage all unhandled exceptions in one place. Instead of writing try-catch blocks everywhere, you can handle errors globally and return consistent, meaningful responses.
In this article, we will explain global exception handling in ASP.NET Core Web API in simple words, how it works, and how to implement it step by step with real-world examples.
What is Exception Handling?
Exception handling is the process of catching and managing runtime errors in an application.
In simple words, when something goes wrong (like a null reference, database error, or invalid input), exception handling ensures the application responds properly instead of crashing.
What is Global Exception Handling?
Global exception handling means handling all exceptions at a central place instead of handling them individually in each controller or method.
Why Use Global Exception Handling?
Avoid repetitive try-catch blocks
Maintain clean and readable code
Return consistent error responses
Improve API security
Easier debugging and logging
Default Exception Behavior in ASP.NET Core
By default, ASP.NET Core shows detailed error pages in development mode but hides them in production.
This is not enough for real-world APIs, where structured error responses are required.
Ways to Handle Exceptions Globally in ASP.NET Core
There are multiple ways to implement global exception handling:
Using built-in middleware (UseExceptionHandler)
Creating custom middleware
Using filters (Exception Filters)
Using Built-in Exception Handling Middleware
ASP.NET Core provides a built-in middleware for handling exceptions.
Example
app.UseExceptionHandler("/error");
app.Map("/error", (HttpContext context) =>
{
return Results.Problem("An unexpected error occurred");
});
This captures all unhandled exceptions and redirects them to a central handler.
Creating Custom Exception Handling Middleware
Custom middleware gives more control over error handling.
Step 1: Create Middleware Class
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
public ExceptionMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
context.Response.ContentType = "application/json";
context.Response.StatusCode = 500;
var response = new
{
StatusCode = context.Response.StatusCode,
Message = "Internal Server Error",
Details = exception.Message
};
return context.Response.WriteAsJsonAsync(response);
}
}
Step 2: Register Middleware
app.UseMiddleware<ExceptionMiddleware>();
Using Exception Filters in ASP.NET Core
Exception filters are used at the controller level.
Example
public class CustomExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
context.Result = new ObjectResult(new
{
Message = "Something went wrong"
})
{
StatusCode = 500
};
}
}
Register Filter
builder.Services.AddControllers(options =>
{
options.Filters.Add<CustomExceptionFilter>();
});
Standard Error Response Format
It is a good practice to return structured error responses.
Example JSON Response
{
"statusCode": 500,
"message": "Internal Server Error",
"details": "Something went wrong"
}
Handling Different Types of Exceptions
You can customize responses based on exception types.
Example
if (exception is KeyNotFoundException)
{
context.Response.StatusCode = 404;
}
else
{
context.Response.StatusCode = 500;
}
Logging Exceptions
Logging is very important for debugging and monitoring.
Example
_logger.LogError(exception, "An error occurred");
You can use built-in logging or tools like Serilog.
Global Exception Handling vs Try-Catch
| Feature | Global Exception Handling | Try-Catch |
|---|
| Scope | Entire application | Specific block |
| Code Reusability | High | Low |
| Maintenance | Easy | Difficult |
| Clean Code | Yes | No |
Real-World Example
In an e-commerce API:
User requests product data
Database fails
Exception is caught globally
API returns structured error response
This improves user experience and debugging.
Common Mistakes to Avoid
1. Exposing Sensitive Information
Do not return stack traces in production.
2. Not Logging Errors
Always log exceptions for analysis.
3. Overusing Try-Catch
Let global handler manage most errors.
Best Practices for Global Exception Handling
Use centralized middleware
Return consistent error format
Log all exceptions
Avoid exposing internal details
Handle specific exceptions differently
Summary
Global exception handling in ASP.NET Core Web API is essential for building robust, secure, and maintainable applications. It allows developers to manage all errors in a centralized way, ensuring consistent responses and better debugging. By using middleware, filters, and proper logging, you can create a reliable API that handles errors gracefully and efficiently.