提问人:p.desterlich 提问时间:8/18/2023 最后编辑:p.desterlich 更新时间:8/21/2023 访问量:93
异常处理的奇怪行为
strange behaviour with exception handling
问:
我有一个 dotnet core 6 API,在异常处理方面存在非常奇怪的行为
- 有一个异常中间件,它应该处理 API 调用中的所有异常(在应用启动中正确实例化)
- 有一个过滤器可以进行一些常见的检查,如果不满足某些条件,就会引发异常
- 控制器中有一个特定的 OnActionExecutionAsync 过程,用于进行特定检查,并在不满足条件时引发另一个异常
public class MyFilter : ActionFilterAttribute
{
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
if (someCondition)
throw new SomeException();
await next();
}
}
[MyFilter]
public class SomeController
{
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
await base.OnActionExecutionAsync(context, next);
if (someOtherCondition)
throw new SomeOtherException();
await next();
}
}
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
public ExceptionMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context, IRequestDataManager requestDataManager)
{
try
{
await _next(context);
}
catch (Exception ex)
{
// handle exception
// if someCondition is met, i expect to have SomeException here
// but instead if appears that SomeController.OnActionExecutionAsync ignore the exception and continue the execution
// so, my problem is that:
// if someCondition AND someOtherCondition are met i get SomeOtherException when i should get SomeException
// if someCondition is met and someOtherCondition is NOT met i get no exception
}
}
}
问题是:
如果不满足筛选器中的条件,则会引发异常,但执行将返回到控制器 OnActionExecutionAsync 并从那里继续执行
如果我逐步调试代码,我可以看到过滤器内部引发的异常,但随后代码返回控制器并继续没有问题
如何在过滤器中引发异常并由异常中间件正确拦截该异常?
编辑:我已经建立了一个带有简单项目的 GitHub 存储库,该项目显示了问题:https://github.com/pdesterlich/webapitest
答:
0赞
Ruikai Feng
8/21/2023
#1
问题通过过滤器的顺序来实现,您可以检查文档,并修改顺序
我根据您的代码尝试如下:
滤波器
public class SomeFilter: ActionFilterAttribute
{
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var constants = new Constants();
if (constants.GenerateException)
throw new Exception("Filter Exception");
await next();
}
}
控制器:
[Route("api/test")]
[SomeFilter(Order = int.MinValue)]
public class SomeController: Controller
{
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var constants = new Constants();
if (constants.GenerateException)
{
throw new Exception("Some Controller Exception");
}
await next();
}
[HttpGet]
public async Task<IActionResult> GetScuole()
{
return Ok("Hello World");
}
}
只需修改控制器中的条件:
if (!constants.GenerateException)
只需修改过滤器中的条件即可
if (!constants.GenerateException)
评论