using System.Text.Json; namespace MyHomePage.Api.Common; /// /// 全局异常处理中间件。 /// 捕获下游抛出的 与未处理异常,统一包装为 。 /// public class ExceptionHandlingMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; private readonly IHostEnvironment _env; public ExceptionHandlingMiddleware( RequestDelegate next, ILogger logger, IHostEnvironment env) { _next = next; _logger = logger; _env = env; } public async Task InvokeAsync(HttpContext context) { try { await _next(context); } catch (BusinessException ex) { _logger.LogWarning("Business exception ({Code}): {Message}", ex.Code, ex.Message); // 使用 ex.Code 透传业务状态码(默认 400/404/500),不再硬编码 200 var status = ex.Code is >= 400 and < 600 ? ex.Code : StatusCodes.Status400BadRequest; await WriteAsync(context, ApiResponse.Fail(ex.Code, ex.Message), status); } catch (Exception ex) { _logger.LogError(ex, "Unhandled exception: {Message}", ex.Message); var message = _env.IsDevelopment() ? ex.Message : "服务器内部错误"; await WriteAsync(context, ApiResponse.Fail(500, message), StatusCodes.Status500InternalServerError); } } private static async Task WriteAsync(HttpContext ctx, object payload, int statusCode) { ctx.Response.StatusCode = statusCode; ctx.Response.ContentType = "application/json; charset=utf-8"; var json = JsonSerializer.Serialize(payload, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); await ctx.Response.WriteAsync(json); } }