I’m currently making a web API with .NET 6.
The code bellow is my Exception handler class:
public class ExceptionsMiddleware
{
private readonly RequestDelegate requestDelegate;
private readonly ILogger<ExceptionsMiddleware> logger;
public ExceptionsMiddleware(RequestDelegate requestDelegate, ILogger<ExceptionsMiddleware> logger)
{
this.requestDelegate = requestDelegate;
this.logger = logger;
}
public async Task Invoke(HttpContext context)
{
try
{
await requestDelegate(context);
}
catch (Exception ex)
{
var response = context.Response;
response.ContentType = "application/json";
var errorMessage = ex.Message;
logger.LogError(ex, "Error occurred");
switch (ex)
{
case ApplicationException:
response.StatusCode = StatusCodes.Status400BadRequest;
break;
case KeyNotFoundException:
case ArgumentException:
case NullReferenceException:
response.StatusCode = StatusCodes.Status404NotFound;
break;
default:
response.StatusCode = StatusCodes.Status500InternalServerError;
errorMessage = "Error occurred";
break;
}
var result = System.Text.Json.JsonSerializer.Serialize(new { Message = errorMessage });
await response.WriteAsync(result);
}
}
}
And in Program.cs class:
app.UseMiddleware<ExceptionsMiddleware>();
This works fine. However, if I want to create a new exception type, I have to modify ExceptionsMiddleware
class again, but the "O" principle in SOLID doesn’t allow me to do this.
Thus, is there any alternative solution for this?
Thank you in advance.
2
Answers
An alternative solution is to handle expected exceptions earlier. The Controller can take the responsibility of creating an appropriate response (
Ok()
,NotFound()
,BadRequest()
, and so on. Based on the result of an action instead of doing all that in your Middleware. You can then use the exception handling middleware to handle unexpected exceptions. It’s a design choice.What you could do is add an extra service into the DI container which the Exceptions handler consumes. The exception handler will forward the exception to the sub-handler, which could be added from a generic base. This is what I came up with. Hope it helps!
EDIT: Original didn’t allow
System.Exception
to be handled.