using System.Text.Json; using FlatRender.ContentSvc.Models.Responses; namespace FlatRender.ContentSvc.Middleware; public class ExceptionMiddleware(RequestDelegate next, ILogger logger) { private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower }; public async Task InvokeAsync(HttpContext ctx) { try { await next(ctx); } catch (Exception ex) { logger.LogError(ex, "Unhandled exception"); await WriteError(ctx, ex); } } private static Task WriteError(HttpContext ctx, Exception ex) { var (status, code) = ex switch { KeyNotFoundException => (404, "not_found"), UnauthorizedAccessException => (401, "unauthorized"), InvalidOperationException => (400, "invalid_operation"), ArgumentException => (400, "bad_request"), NotImplementedException => (501, "not_implemented"), _ => (500, "internal_error") }; ctx.Response.StatusCode = status; ctx.Response.ContentType = "application/json"; var error = new { error = new ApiError(code, ex.Message, ctx.TraceIdentifier) }; return ctx.Response.WriteAsync(JsonSerializer.Serialize(error, JsonOptions)); } }