There are some ways to handle exceptions while we working with ASP.NET Core
1. Use try-catch block
Best practice when using "throw"
Throw ex: loose stack trace on downstream layer
For example, an exception has occurred in the Data layer, Business layer catch this exception and use 'Throw Ex', at API layer will lose stack traceThrow: keep stack trace on downstream layer
For example, an exception has occurred in the Data layer, Business layer catch this exception and use 'Throw', at API layer will get a stack trace in detailThrow new Exception/ or Custom Exception: it will make downstream layer losing stack trace in detail
Only use at a lower level, the downstream level should use "Throw", we will keep stack trace on the downstream level
2. Use custom middleware to centralize exception handling
/// <summary>
/// Step 1: Create a middleware class
/// </summary>
public class CustomExceptionHandlerMiddleware
{
private readonly RequestDelegate _next;
ILogger<CustomExceptionHandlerMiddleware> _logger;
public CustomExceptionHandlerMiddleware(RequestDelegate next
, ILogger<CustomExceptionHandlerMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while processing your request");
await HandleExceptionAsync(context, ex);
}
}
private Task HandleExceptionAsync(HttpContext context, Exception exception)
{
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return context.Response.WriteAsync(exception.Message);
}
}
/// <summary>
/// Step 2: Create a extension method to use our middleware
/// </summary>
public static class CustomExceptionHandlerMiddlewareExtensions
{
public static IApplicationBuilder UseCustomExceptionHandlers(this IApplicationBuilder app)
{
return app.UseMiddleware<CustomExceptionHandlerMiddleware>();
}
}
3. Centralize exception handling with IExceptionFilter
Implement an ExceptionFilter class
Add to the configuration method (Sample for ASP.NET Core 3.0)
Throw an exception when needed.
4. [From ASP.NET Core 8] - Use IExceptionHandler
This interface has TryHandleAsync method.
If Exception can handle => return true;
If Not => return false
Implement of IExceptionHandler
public class GlobalExceptionHandler : IExceptionHandler
{
private readonly ILogger<GlobalExceptionHandler> logger;
public GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger)
{
this.logger = logger;
}
public async ValueTask<bool> TryHandleAsync(
HttpContext httpContext,
Exception exception,
CancellationToken cancellationToken)
{
this.logger.LogError(exception, "Exception occurred: {Message}", exception.Message);
var problemDetails = new ProblemDetails
{
Status = StatusCodes.Status500InternalServerError,
Title = "Server error -- apply IExceptionHandler for Global"
};
httpContext.Response.StatusCode = problemDetails.Status.Value;
await httpContext.Response
.WriteAsJsonAsync(problemDetails, cancellationToken);
return true;
}
}
Use the handler in Program file
// User Exception Handler
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();



Top comments (0)