using System.Net; using System.Text.Json; using UniVerse.Domain.Exceptions; namespace UniVerse.Api.Middleware; public class ExceptionHandlingMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; public ExceptionHandlingMiddleware(RequestDelegate next, ILogger logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { try { await _next(context); } catch (Exception ex) { await HandleExceptionAsync(context, ex); } } private async Task HandleExceptionAsync(HttpContext context, Exception exception) { var (statusCode, title) = exception switch { NotFoundException => ((int)HttpStatusCode.NotFound, "Not Found"), ForbiddenException => ((int)HttpStatusCode.Forbidden, "Forbidden"), ConflictException => ((int)HttpStatusCode.Conflict, "Conflict"), UnauthorizedAccessException => ((int)HttpStatusCode.Unauthorized, "Unauthorized"), _ => ((int)HttpStatusCode.InternalServerError, "Internal Server Error") }; if (statusCode == 500) _logger.LogError(exception, "Unhandled exception"); else _logger.LogWarning("Handled exception: {Message}", exception.Message); context.Response.ContentType = "application/problem+json"; context.Response.StatusCode = statusCode; var problem = new { type = $"https://httpstatuses.com/{statusCode}", title, status = statusCode, detail = exception.Message, traceId = context.TraceIdentifier }; await context.Response.WriteAsync(JsonSerializer.Serialize(problem, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })); } }