65 private static readonly Action<ILogger, string, Exception?> LogRequestFailure =
66 LoggerMessage.Define<
string>(
69 "Request failed: {Message}");
71 private readonly RequestDelegate _next;
73 private readonly ILogger<ExceptionHandlingMiddleware> _logger;
77 ILogger<ExceptionHandlingMiddleware> logger)
85 ArgumentNullException.ThrowIfNull(context);
89 await _next(context).ConfigureAwait(
false);
91#pragma warning disable CA1031
93#pragma warning restore CA1031
95 LogRequestFailure(_logger, ex.Message, ex);
96 await HandleExceptionAsync(context, ex).ConfigureAwait(
false);
100 private static Task HandleExceptionAsync(HttpContext context,
Exception exception)
102 context.Response.ContentType =
"application/json";
103 var (statusCode, problemDetails) = exception
switch
106 StatusCodes.Status400BadRequest,
107 (ProblemDetails)
new ValidationProblemDetails(ve.
Errors)
109 Title =
"Validation failed",
110 Status = StatusCodes.Status400BadRequest
113 StatusCodes.Status404NotFound,
116 Title =
"Resource not found",
118 Status = StatusCodes.Status404NotFound
121 StatusCodes.Status422UnprocessableEntity,
124 Title =
"Business rule violation",
126 Status = StatusCodes.Status422UnprocessableEntity
129 StatusCodes.Status500InternalServerError,
132 Title =
"An unexpected error occurred",
133 Status = StatusCodes.Status500InternalServerError,
134 Detail =
"Please try again later or contact support."
137 context.Response.StatusCode = statusCode;
138 return context.Response.WriteAsJsonAsync(problemDetails);