using System.Net; using System.Text.Json; using FlatRender.IdentitySvc.Models.Responses; namespace FlatRender.IdentitySvc.Middleware; public class ExceptionMiddleware(RequestDelegate next, ILogger logger) { private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower }; public async Task InvokeAsync(HttpContext context) { try { await next(context); } catch (Exception ex) { await HandleExceptionAsync(context, ex); } } private async Task HandleExceptionAsync(HttpContext context, Exception ex) { var traceId = context.TraceIdentifier; var (status, code, message) = ex switch { KeyNotFoundException => (HttpStatusCode.NotFound, "NOT_FOUND", ex.Message), UnauthorizedAccessException => (HttpStatusCode.Unauthorized, "UNAUTHORIZED", ex.Message), InvalidOperationException => (HttpStatusCode.BadRequest, "INVALID_OPERATION", ex.Message), ArgumentException => (HttpStatusCode.BadRequest, "INVALID_ARGUMENT", ex.Message), NotImplementedException => (HttpStatusCode.NotImplemented, "NOT_IMPLEMENTED", ex.Message), _ => (HttpStatusCode.InternalServerError, "INTERNAL_ERROR", "An unexpected error occurred"), }; if (status == HttpStatusCode.InternalServerError) logger.LogError(ex, "Unhandled exception {TraceId}", traceId); context.Response.StatusCode = (int)status; context.Response.ContentType = "application/json"; var body = JsonSerializer.Serialize( new { error = new ApiError(code, message, null, traceId) }, JsonOptions); await context.Response.WriteAsync(body); } }