using System.Net; using System.Text.Json; namespace CodePlay.WebAPI.Middleware; /// /// 全局异常处理中间件 /// public class GlobalExceptionHandler { private readonly RequestDelegate _next; private readonly ILogger _logger; public GlobalExceptionHandler(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 response = context.Response; response.ContentType = "application/json"; var errorResponse = new ErrorResponse { RequestId = context.TraceIdentifier, Timestamp = DateTime.UtcNow, Path = context.Request.Path, Method = context.Request.Method }; switch (exception) { case UnauthorizedAccessException: response.StatusCode = (int)HttpStatusCode.Unauthorized; errorResponse.Code = "UNAUTHORIZED"; errorResponse.Message = "未授权访问"; _logger.LogWarning(exception, "未授权访问尝试"); break; case ArgumentException argumentEx: response.StatusCode = (int)HttpStatusCode.BadRequest; errorResponse.Code = "BAD_REQUEST"; errorResponse.Message = argumentEx.Message; _logger.LogWarning(exception, "参数验证失败"); break; case KeyNotFoundException: response.StatusCode = (int)HttpStatusCode.NotFound; errorResponse.Code = "NOT_FOUND"; errorResponse.Message = "资源不存在"; _logger.LogWarning(exception, "资源未找到"); break; case InvalidOperationException invalidEx: response.StatusCode = (int)HttpStatusCode.Conflict; errorResponse.Code = "CONFLICT"; errorResponse.Message = invalidEx.Message; _logger.LogWarning(exception, "操作无效"); break; case TimeoutException: response.StatusCode = (int)HttpStatusCode.GatewayTimeout; errorResponse.Code = "TIMEOUT"; errorResponse.Message = "请求超时"; _logger.LogError(exception, "请求超时"); break; default: response.StatusCode = (int)HttpStatusCode.InternalServerError; errorResponse.Code = "INTERNAL_ERROR"; errorResponse.Message = "服务器内部错误"; _logger.LogError(exception, "未处理的异常"); break; } var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true }; var jsonResponse = JsonSerializer.Serialize(errorResponse, options); await response.WriteAsync(jsonResponse); } } /// /// 错误响应模型 /// public class ErrorResponse { public string RequestId { get; set; } = ""; public DateTime Timestamp { get; set; } public string Code { get; set; } = ""; public string Message { get; set; } = ""; public string Path { get; set; } = ""; public string Method { get; set; } = ""; public Dictionary? Details { get; set; } } /// /// 中间件扩展 /// public static class GlobalExceptionHandlerExtensions { public static IApplicationBuilder UseGlobalExceptionHandler(this IApplicationBuilder app) { return app.UseMiddleware(); } }