|
@@ -1,4 +1,6 @@
|
|
|
|
|
|
|
|
+using Microsoft.Data.SqlClient;
|
|
|
|
+
|
|
namespace OASystem.API.Middlewares
|
|
namespace OASystem.API.Middlewares
|
|
{
|
|
{
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -8,22 +10,26 @@ namespace OASystem.API.Middlewares
|
|
{
|
|
{
|
|
private readonly RequestDelegate _next; // 用来处理上下文请求
|
|
private readonly RequestDelegate _next; // 用来处理上下文请求
|
|
private readonly ILogger<ExceptionHandlingMiddleware> _logger;
|
|
private readonly ILogger<ExceptionHandlingMiddleware> _logger;
|
|
|
|
+ private readonly SqlSugarClient _db;
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// 初始化
|
|
/// 初始化
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <param name="next"></param>
|
|
/// <param name="next"></param>
|
|
/// <param name="logger"></param>
|
|
/// <param name="logger"></param>
|
|
- public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger)
|
|
|
|
|
|
+ /// <param name="db"></param>
|
|
|
|
+ public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger, SqlSugarClient db)
|
|
{
|
|
{
|
|
_next = next;
|
|
_next = next;
|
|
_logger = logger;
|
|
_logger = logger;
|
|
|
|
+ _db = db;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// 执行中间件
|
|
/// 执行中间件
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <param name="httpContext"></param>
|
|
/// <param name="httpContext"></param>
|
|
|
|
+ /// <param name="db"></param>
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
public async Task InvokeAsync(HttpContext httpContext, SqlSugarClient db)
|
|
public async Task InvokeAsync(HttpContext httpContext, SqlSugarClient db)
|
|
{
|
|
{
|
|
@@ -38,57 +44,83 @@ namespace OASystem.API.Middlewares
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// 异步处理异常
|
|
|
|
|
|
+ /// 自定义全局异常处理方法
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="context"></param>
|
|
/// <param name="exception"></param>
|
|
/// <param name="exception"></param>
|
|
|
|
+ /// <param name="db"></param>
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
private async Task HandleExceptionAsync(HttpContext context, Exception exception, SqlSugarClient db)
|
|
private async Task HandleExceptionAsync(HttpContext context, Exception exception, SqlSugarClient db)
|
|
{
|
|
{
|
|
if (db.Ado != null && db.Ado.Transaction != null)
|
|
if (db.Ado != null && db.Ado.Transaction != null)
|
|
{
|
|
{
|
|
- db.Ado.RollbackTran();
|
|
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ db.Ado.RollbackTran();
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex)
|
|
|
|
+ {
|
|
|
|
+ _logger.LogError("Error rolling back transaction: {ErrorMessage}", ex.Message);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- context.Response.ContentType = "application/json"; // 返回json 类型
|
|
|
|
- var response = context.Response;
|
|
|
|
- var errorResponse = new JsonView
|
|
|
|
- {
|
|
|
|
- Code = StatusCodes.Status500InternalServerError,
|
|
|
|
- Data = ""
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- // 自定义的异常错误信息类型
|
|
|
|
- switch (exception)
|
|
|
|
|
|
+ // 检查响应是否已开始
|
|
|
|
+ if (!context.Response.HasStarted)
|
|
{
|
|
{
|
|
- case ApplicationException ex:
|
|
|
|
- if (ex.Message.Contains("Invalid token"))
|
|
|
|
- {
|
|
|
|
|
|
+ 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;
|
|
response.StatusCode = StatusCodes.Status403Forbidden;
|
|
errorResponse.Msg = ex.Message;
|
|
errorResponse.Msg = ex.Message;
|
|
break;
|
|
break;
|
|
- }
|
|
|
|
- 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 = StatusCodes.Status204NoContent;
|
|
|
|
- if (ex.Message.Contains("timeout")) errorResponse.Msg = $"数据库连接超时,请稍后重试。";
|
|
|
|
- else errorResponse.Msg = ex.Message;
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- response.StatusCode = StatusCodes.Status500InternalServerError;
|
|
|
|
- errorResponse.Msg = exception.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.Message);
|
|
|
|
- var result = JsonConvert.SerializeObject(errorResponse);
|
|
|
|
- await context.Response.WriteAsync(result);
|
|
|
|
|
|
+ _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.");
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|