Csharp Master – Global Exception Handler in .NET Core 7 & .Net Core 8 Web API (2024)
Here in this article, we will get to know the concept of a global exception handler in .NET Core, its benefits, and how to implement effectively.
In modern software development, managing exceptions efficiently is crucial for building robust applications. One of the best practices in handling exceptions is to implement a global exception handler.
What is a Global Exception Handler?
A global exception handler is a centralized mechanism for catching unhandled or unexpected errors in an application. In .NET Core, this allows developers to manage errors consistently across the whole application. by this application’s maintainability and reliability is also gets improved. Instead of handling exceptions in multiple places, you define a single point of control that deals with any unexpected errors.
Benefits Global Exception Handler in .NET Core
Centralized Error Management
A global exception handler provides a single location for handling exceptions, making your code cleaner and more maintainable. This centralization ensures that all unhandled exceptions are caught and processed uniformly.
Learn about HashMap in c#.
Better User Experience
By implementing a global exception handler, you can present user-friendly error messages instead of raw exception details, which improve the overall user experience. This approach helps in maintaining the professionalism of your application.
Enhanced Security
Exposing detailed error information can be a security risk. A global exception handler can log the necessary details while showing generic messages to the users, thereby protecting sensitive information.
Simplified Debugging and Logging
With a global exception handler, you can log errors consistently, making it easier to diagnose issues. This central logging can be crucial for debugging and monitoring the health of your application.
Implementation a Global Exception Handler in .NET Core 7
Old way to create Global Exception Handler in .NET Core 7
Step 1: Creating a Middleware
In .NET Core, middleware is a natural place to implement a global exception handler. Middleware is a component that processes HTTP requests and responses.
- Create a Middleware Class in c#
Step 2: Registering the Middleware
Next, register the middleware in the Startup.cs
file.
public class Startup
{
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMiddleware<GlobalExceptionHandlerMiddleware>();
// Other middlewares
app.UseMvc();
}
}
Step 3: Customizing the Response
To make the exception handler more informative, you can customize the error response based on different types of exceptions.
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
var code = HttpStatusCode.InternalServerError; // 500 status code if unexpected
if (exception is ArgumentNullException) code = HttpStatusCode.BadRequest;
else if (exception is UnauthorizedAccessException) code = HttpStatusCode.Unauthorized;
var result = JsonConvert.SerializeObject(new { error = exception.Message });
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)code;
return context.Response.WriteAsync(result);
}
Step 4: Logging
For a robust application, logging is essential. There are several logging framework like NLog, Serilog, or the built-in .NET Core logging which we can use as per usecase.
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
// Example using Serilog
Log.Error(exception, "Unhandled exception occurred");
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
var response = new { message = "Internal Server Error. Please try again later." };
return context.Response.WriteAsync(JsonConvert.SerializeObject(response));
}
New way to Create Global Exception Handling in .NET Core 8
Now we have New way to Create Global Exception Handling in .NET Core 8
Step-by-Step Implementation
Step 1: Creating the Exception Handler
First, define a class that implements IExceptionHandler
.
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.Net;
using System.Text.Json;
using System.Threading.Tasks;
public class GlobalExceptionHandler : IExceptionHandler
{
private readonly ILogger<GlobalExceptionHandler> _logger;
public GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger)
{
_logger = logger;
}
public async Task HandleExceptionAsync(HttpContext context, Exception exception)
{
_logger.LogError(exception, "Unhandled exception occurred");
var response = context.Response;
response.ContentType = "application/json";
response.StatusCode = (int)GetStatusCode(exception);
var result = JsonSerializer.Serialize(new { error = exception.Message });
await response.WriteAsync(result);
}
private static HttpStatusCode GetStatusCode(Exception exception)
{
return exception switch
{
ArgumentNullException => HttpStatusCode.BadRequest,
UnauthorizedAccessException => HttpStatusCode.Unauthorized,
_ => HttpStatusCode.InternalServerError
};
}
}
Step 2: Registering the Exception Handler
Register the exception handler in the Startup.cs
file (or Program.cs
for minimal hosting).
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IExceptionHandler, GlobalExceptionHandler>();
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/error");
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Step 3: Creating an Error Handling Endpoint
Create a controller to handle error responses.
[ApiController]
public class ErrorController : ControllerBase
{
private readonly IExceptionHandler _exceptionHandler;
public ErrorController(IExceptionHandler exceptionHandler)
{
_exceptionHandler = exceptionHandler;
}
[Route("error")]
public async Task Error()
{
var context = HttpContext.Features.Get<IExceptionHandlerFeature>();
if (context != null)
{
await _exceptionHandler.HandleExceptionAsync(HttpContext, context.Error);
}
}
}
Step 4: Configuring Middleware for Exception Handling
Ensure your middleware setup in Program.cs
:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Step 5: Testing the Implementation
Create an endpoint to test the exception handling.
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
[HttpGet("throw")]
public IActionResult Throw()
{
throw new ArgumentNullException("This is a test exception.");
}
}
Best Practices for Global Exception Handling in .NET Core
Use Specific Exceptions
Handle specific exceptions first before the general exception to provide more precise error handling. This helps in identifying and resolving issues fast.
Avoid Swallowing Exceptions
Ensure that all exceptions are logged and not just swallowed. Swallowing exceptions can lead to silent failures, making debugging difficult.
Learn about async and await in c# with example.
Secure Exception Information
Never expose stack traces or sensitive information to the end user. Always log such details securely for debugging purposes.
Consistent Error Responses
Provide consistent error responses to the client. This can be achieved by defining a standard error response format and ensuring all exceptions are transformed into this format.
Testing
Thoroughly test your global exception handler to ensure it behaves as expected under various scenarios. This includes testing with different types of exceptions and verifying the error responses.
Conclusion
Its very important to Implement global exception handler in .NET Core to build resilient and maintainable applications. It centralizes error management, improves user experience, enhances security, and simplifies debugging and logging. By following best practices and customizing the handler according to your application’s needs, you can ensure that application handles unhandled or unexpected exceptions/errors gracefully and professionally and provide meaningful message.
Service Tag: – Csharpmaster | Csharp Master | c# quiz | Fluent Validation in .NET Core | monolithic and microservices architecture | Global Exception Handler in .NET Core | HashMap in C# | Dictionary in C# | split string in c# |Open Closed Principle in C#| liskov substitution principle c# example | Difference Between Async and Await in C# | Difference Between String and StringBuilder in C# | What is Delegate in C# with Example | dependency injection in .NET Core | Lambda Expression in C# | Design Patterns in C# with Examples | Boxing and Unboxing in C# with Example | Collection in C# with Example | How to split string in ca comprehensive guide | Implement open closed principle in csharp example | Difference between async and await in c with-example | string and stringbuilder in csharp with example csharp master tutorial | lambda expression in c with example
- Enum Data Type in PostgreSQL with Practical Examples
- Understanding the Repository Design Pattern in C#
- What is DTO in C# with Example | Data Transfer Object Design Pattern | C# Master
- Understanding POCO Class in C#
- CSharpMaster’s C# Quiz for Beginner
- Using Fluent Validation in .NET Core 8 with Example
- CsharpMaster – Difference Between Monolithic and Microservices Architecture with Example
- Csharp Master – Global Exception Handler in .NET Core 7 & .Net Core 8 Web API (2024)
- Understanding What is HashMap in C# with Example (2024)
- CSharp Master’s Guide to Using Dictionary in C# (Key-value pair) – 2024
- CSharpMaster – How to Split String in C# (String.Split() with string delimiter)
- CSharpMaster – How to Implement Open Closed Principle in C# Example (SOLID)
- Understanding liskov principle c# | liskov substitution principle c# example
- Difference Between Async and Await in C# with Example – C# asynchronous programming 2024
- Difference Between String and StringBuilder in C# with example – Csharp Master Tutorial