| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 | using Microsoft.Data.SqlClient;namespace OASystem.API.Middlewares{    /// <summary>    /// 全局异常捕获中间件    /// </summary>    public class ExceptionHandlingMiddleware    {        private readonly RequestDelegate _next;  // 用来处理上下文请求        private readonly ILogger<ExceptionHandlingMiddleware> _logger;        /// <summary>        /// 初始化        /// </summary>        /// <param name="next"></param>        /// <param name="logger"></param>        public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger)        {            _next = next;            _logger = logger;        }        /// <summary>        /// 执行中间件        /// </summary>        /// <param name="httpContext"></param>        /// <param name="db"></param>        /// <returns></returns>        public async Task InvokeAsync(HttpContext httpContext, SqlSugarClient db)        {            try            {                await _next(httpContext); //要么在中间件中处理,要么被传递到下一个中间件中去            }            catch (Exception ex)            {                await HandleExceptionAsync(httpContext, ex, db); // 捕获异常了 在HandleExceptionAsync中处理            }        }        /// <summary>        /// 自定义全局异常处理方法        /// </summary>        /// <param name="context"></param>        /// <param name="exception"></param>        /// <param name="db"></param>        /// <returns></returns>        private async Task HandleExceptionAsync(HttpContext context, Exception exception, SqlSugarClient db)        {            //if (db.Ado != null && db.Ado.Transaction != null)            //{            //    try            //    {            //        db.Ado.RollbackTran();            //    }            //    catch (Exception ex)            //    {            //        _logger.LogError("Error rolling back transaction: {ErrorMessage}", ex.Message);            //    }            //}            // 检查响应是否已开始            if (!context.Response.HasStarted)            {                context.Response.ContentType = "application/json"; // 设置响应内容类型为 JSON                var response = context.Response;                var errorResponse = new JsonView                {                    Code = StatusCodes.Status500InternalServerError,                    Data = ""                };                // 根据异常类型设置不同的响应状态码和消息                switch (exception)                {                    case SqlException sqlEx when sqlEx.Number == -2:                        response.StatusCode = StatusCodes.Status503ServiceUnavailable;                        errorResponse.Msg = "数据库连接超时,请稍后重试。";                        break;                    case SqlException sqlEx when sqlEx.Number == -4:                        response.StatusCode = StatusCodes.Status503ServiceUnavailable;                        errorResponse.Msg = "数据库连接池耗尽,请稍后重试。";                        break;                    case ApplicationException ex when ex.Message.Contains("Invalid token"):                        response.StatusCode = StatusCodes.Status403Forbidden;                        errorResponse.Msg = ex.Message;                        break;                    case ApplicationException ex:                        response.StatusCode = StatusCodes.Status400BadRequest;                        errorResponse.Msg = ex.Message;                        break;                    case KeyNotFoundException ex:                        response.StatusCode = StatusCodes.Status404NotFound;                        errorResponse.Msg = ex.Message;                        break;                    case SqlSugarException ex:                        response.StatusCode = ex.Message.Contains("timeout")                            ? StatusCodes.Status503ServiceUnavailable                            : StatusCodes.Status500InternalServerError;                        errorResponse.Msg = ex.Message.Contains("timeout")                            ? "数据库连接超时,请稍后重试。"                            : ex.Message;                        break;                    default:                        response.StatusCode = StatusCodes.Status500InternalServerError;                        errorResponse.Msg = "服务器内部错误"; // 不直接暴露异常详细信息                        break;                }                _logger.LogError(exception, "An exception occurred."); // 记录异常详细信息                var result = JsonConvert.SerializeObject(errorResponse);                await context.Response.WriteAsync(result); // 将错误响应写入客户端            }            else            {                // 如果响应已开始,记录日志但不做进一步处理                _logger.LogError(exception, "An exception occurred after response started.");            }        }    }}
 |