You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8中ASP.NET Core全局异常处理中间件失效问题排查

.NET 8 ASP.NET Core 全局异常处理不生效的排查与解决

核心问题:中间件顺序错误

你的全局异常处理未生效的主要原因是**UseExceptionHandler中间件的位置不对**。ASP.NET Core的中间件按注册顺序执行,异常处理中间件必须放在所有可能抛出异常的中间件之前,才能捕获它们的异常。

当前你的UseExceptionHandler在UseWhen、UseCors、UseHttpsRedirection之后,这些中间件如果抛出异常,异常处理中间件根本没机会捕获。

修复步骤

1. 调整中间件顺序

将app.UseExceptionHandler();移动到请求管道的最前端(开发环境Swagger配置之后),确保它在所有业务中间件之前:

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "Hospital System APIv1");
    });
}

// 把异常处理中间件放在最前面
app.UseExceptionHandler();

app.UseWhen(context => !context.Request.Path.StartsWithSegments("/api/auth"), appBuilder =>
{
    appBuilder.UseMiddleware<VerifyTokenMiddleware>();
});

app.UseCors(x => x 
    .AllowAnyOrigin()
    .AllowAnyHeader()
    .AllowAnyMethod()
);

app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthentication();

app.UseAuthorization();

app.MapControllers();

app.Run();

2. 检查自定义中间件是否拦截异常

检查你的VerifyTokenMiddleware,如果它内部捕获了异常但没有重新抛出,全局异常处理器将无法收到异常。例如,如果中间件里有类似下面的代码:

try
{
    // 中间件逻辑
}
catch(Exception ex)
{
    // 只记录日志但不抛出
    _logger.LogError(ex, "Token验证失败");
}

这种情况下,需要修改为重新抛出异常,或者直接不捕获让异常向上传递:

try
{
    // 中间件逻辑
}
catch(Exception ex)
{
    _logger.LogError(ex, "Token验证失败");
    throw; // 重新抛出,让全局异常处理器处理
}

3. 验证异常处理器逻辑

你的AppExceptionHandler逻辑本身没有问题,但可以添加日志来确认是否被触发:

// 注入ILogger
private readonly ILogger<AppExceptionHandler> _logger;

public AppExceptionHandler(ILogger<AppExceptionHandler> logger)
{
    _logger = logger;
}

public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
{
    _logger.LogError(exception, "全局异常捕获"); // 添加日志
    
    var statusCode = (int)HttpStatusCode.InternalServerError;
    httpContext.Response.StatusCode = statusCode;
    var problem = new ProblemDetails
    {
        Status = statusCode,
        Title = "Server Error",
        Detail = exception.Message,
    };
    var json = JsonSerializer.Serialize(problem);
    httpContext.Response.ContentType = "application/json";
    await httpContext.Response.WriteAsync(json, cancellationToken);
    return true;
}

这样可以通过日志确认处理器是否被调用,帮助排查问题。

额外注意事项

  • 开发环境下,如果之前启用了开发者异常页面(默认启用),UseExceptionHandler会覆盖它,但确保顺序正确才能生效。
  • 如果你使用了[ApiController]特性,默认的问题细节处理可能会和自定义处理器交互,确保AddProblemDetails()已经正确注册(你已经加了,没问题)。

内容的提问来源于stack exchange,提问作者Mohamed Saeed bin Omar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 13:35:00