using System.Net; using Microsoft.AspNetCore.Http.HttpResults; namespace DrinkRateAPI.Exceptions; public record ExceptionResponse(int StatusCode, string Description); 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) { _logger.LogError(exception, "An error occurred."); var defaultResponse = exception switch { BadRequestException _ => new ExceptionResponse(StatusCodes.Status400BadRequest, "Application exception occurred."), NotFoundException _ => new ExceptionResponse(StatusCodes.Status404NotFound, "The request key not found."), UnauthenticatedException _ => new ExceptionResponse(StatusCodes.Status401Unauthorized, "Unauthorized."), PaymentRequiredException _ => new ExceptionResponse(StatusCodes.Status402PaymentRequired, "Payment required."), ForbiddenException _ => new ExceptionResponse(StatusCodes.Status403Forbidden, "Forbidden."), IamATeapotException _ => new ExceptionResponse(StatusCodes.Status418ImATeapot, "I am a teapot."), UnavailableForLagalReasonsException _ => new ExceptionResponse(StatusCodes.Status451UnavailableForLegalReasons, "Unavailable for legal reasons."), _ => new ExceptionResponse(StatusCodes.Status500InternalServerError, "Internal server error. Please retry later.") }; var description = !string.IsNullOrWhiteSpace(exception.Message) ? exception.Message : defaultResponse.Description; var response = defaultResponse with { Description = description }; context.Response.ContentType = "application/json"; context.Response.StatusCode = response.StatusCode; await context.Response.WriteAsJsonAsync(response); } }