问题描述
我在启动
(更新:解决方案是将 UseRouting 移动到 /api/error 路由下)
app.UseRouting();
if (env.IsDevelopment()) {
app.UseExceptionHandler("/api/error/error-local-development");
SwaggerConfig.Configure(app);
}
else {
app.UseExceptionHandler("/api/error/error");
}
app.UseCors();
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseSpaStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.UseRequestLocalization(options);
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<ResultHub>("/hubs/resultHub");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "wwwroot";
});
但是当 throw new Exception()
在控制器操作中时,错误控制器方法永远不会被调用。
[Route("api/error")]
[ApiController]
[ApiExplorerSettings(IgnoreApi = true)]
public class ErrorController : OwnBaseController
{
public ErrorController(IApplicationUserService applicationUserService,ILogger<ErrorController> logger,IDiagnosticContext diagnosticContext) : base(applicationUserService,logger,diagnosticContext)
{
}
[Route("error")]
public IActionResult Error()
{
return Problem();
}
[Route("error-local-development")]
public IActionResult ErrorLocalDevelopment([FromServices] IWebHostEnvironment webHostEnvironment)
{
var context = HttpContext.Features.Get<IExceptionHandlerFeature>();
return Problem(
detail: context.Error.StackTrace,title: context.Error.Message);
}
}
解决方法
这可能看起来很奇怪,但顺序很重要。
UseExceptionHandler
和 UseRouting
都在后台注册中间件。
首先注册的将是最外层的中间件。因此,如果内部抛出异常,外部可以捕获并处理(和/或记录)它。
MSDN 对此有一些警告,例如:
如果指定了应用内的端点,则为该端点创建 MVC 视图或 Razor 页面。确保将 UseStatusCodePagesWithReExecute
放在 UseRouting
之前,以便可以将请求重新路由到状态页面。
UseExceptionHandler
是添加到管道中的第一个中间件组件。因此,异常处理程序中间件会捕获后续调用中发生的任何异常。