Files
QYZH.InteractiveMagazine/QYZH.InteractiveMagazine.Infrastructure/Middleware/GlobalExceptionMiddleware.cs

111 lines
4.0 KiB
C#
Raw Normal View History

2026-06-01 13:42:40 +08:00
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using System.Text.Json;
namespace QYZH.InteractiveMagazine.Infrastructure.Middleware;
/// <summary>
/// 全局异常中间件
/// </summary>
public class GlobalExceptionMiddleware : IMiddleware
{
private readonly ILogger<GlobalExceptionMiddleware> _logger;
/// <summary>
/// JSON序列化选项camelCase与Controller保持一致
/// </summary>
private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
2026-06-01 13:42:40 +08:00
/// <summary>
/// 构造函数
/// </summary>
/// <param name="logger">日志记录器</param>
public GlobalExceptionMiddleware(ILogger<GlobalExceptionMiddleware> logger)
{
_logger = logger;
}
/// <summary>
/// 执行中间件
/// </summary>
/// <param name="context">HTTP上下文</param>
/// <param name="next">下一个中间件委托</param>
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
try
{
await next(context);
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "业务异常:{Message},状态码:{ResultCode}", ex.Message, ex.ResultCode);
2026-06-01 13:42:40 +08:00
await HandleBusinessExceptionAsync(context, ex);
}
catch (Exception ex)
{
_logger.LogError(ex, "系统异常:{Message}", ex.Message);
await HandleSystemExceptionAsync(context, ex);
}
}
/// <summary>
/// 处理业务异常按业务状态码映射HTTP状态码
2026-06-01 13:42:40 +08:00
/// </summary>
/// <param name="context">HTTP上下文</param>
/// <param name="ex">业务异常</param>
private static async Task HandleBusinessExceptionAsync(HttpContext context, BusinessException ex)
{
context.Response.ContentType = "application/json";
context.Response.StatusCode = GetHttpStatusCode(ex.ResultCode);
2026-06-01 13:42:40 +08:00
var response = BaseResponse<object>.Fail(ex.ResultCode, ex.Message);
var json = JsonSerializer.Serialize(response, JsonOptions);
2026-06-01 13:42:40 +08:00
await context.Response.WriteAsync(json);
}
/// <summary>
/// 处理系统异常
/// </summary>
/// <param name="context">HTTP上下文</param>
/// <param name="ex">系统异常</param>
private static async Task HandleSystemExceptionAsync(HttpContext context, Exception ex)
{
context.Response.ContentType = "application/json";
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
var response = BaseResponse<object>.Fail(ResultCode.GLOBAL_ERROR, "系统内部错误,请稍后重试");
var json = JsonSerializer.Serialize(response, JsonOptions);
2026-06-01 13:42:40 +08:00
await context.Response.WriteAsync(json);
}
/// <summary>
/// 根据业务状态码获取对应的HTTP状态码
/// </summary>
/// <param name="resultCode">业务状态码</param>
/// <returns>HTTP状态码</returns>
private static int GetHttpStatusCode(ResultCode resultCode)
{
return resultCode switch
{
ResultCode.DENY => StatusCodes.Status401Unauthorized,
ResultCode.FORBIDDEN => StatusCodes.Status403Forbidden,
ResultCode.NOT_FOUND => StatusCodes.Status404NotFound,
ResultCode.BAD_REQUEST => StatusCodes.Status400BadRequest,
ResultCode.PARAM_ERROR => StatusCodes.Status400BadRequest,
ResultCode.CONFLICT => StatusCodes.Status409Conflict,
ResultCode.UNPROCESSABLE_ENTITY => StatusCodes.Status422UnprocessableEntity,
ResultCode.TOO_MANY_REQUESTS => StatusCodes.Status429TooManyRequests,
ResultCode.BAD_GATEWAY => StatusCodes.Status502BadGateway,
ResultCode.SERVICE_UNAVAILABLE => StatusCodes.Status503ServiceUnavailable,
_ => StatusCodes.Status400BadRequest
};
}
2026-06-01 13:42:40 +08:00
}