Web API 2 -全局异常处理程序不能与taskcancel一起工作
本文关键字:taskcancel 一起 工作 不能 异常处理程序 API 全局 Web | 更新日期: 2023-09-27 18:12:35
演示问题的代码:
- 假设Test Thing是一个真实的实现,比如DB调用。
- Web API的文档说明,未处理的异常将被捕获在一个全局处理程序中,允许你处理它们。
- 如果我用ExceptionFilter代替MyErrorHandler,这确实有效,除了我正在使用处理程序的代码库,因为错误逻辑是一个横切关注点,无论错误来自何处,都是相同的。
- 如果抛出的异常类型不是TaskCancelledException,则按预期调用处理程序。
- 我也尝试了最新版本的Web API(5.2.3)。
- 唯一的工作是在可以抛出这种类型异常的任何地方添加一个try/catch块,不用说这是痛苦的,也是我希望避免使用处理程序的事情。
我不想把这叫做bug,因为这不是我的代码,但经过几个小时的尝试,它开始感觉是这样的。
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.ExceptionHandling;
namespace WebApplication3.Controllers
{
public class TestController : ApiController
{
public async Task<string> Get()
{
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(1));
return await new TestThing().ExecuteAsync(cancellationTokenSource.Token);
}
}
public class MyErrorHandler : ExceptionHandler
{
public override Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
}
public class TestThing
{
public async Task<string> ExecuteAsync(CancellationToken cancellationToken)
{
// Remove this to see the problem, I don't want to add these
// try/catch statements all over the codebase.
try
{
await Task.Delay(TimeSpan.FromMinutes(1), cancellationToken);
}
catch (Exception ex)
{
throw new Exception("Failure...");
}
return await Task.FromResult("Testing...");
}
}
}
由于缺乏建议或答案,我使用了自定义消息处理程序。
public class AsyncFixHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
try
{
return await base.SendAsync(request, cancellationToken);
}
catch (TaskCanceledException)
{
// TODO: Log the issue here
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
}
}
这不是理想的,但是try/catch是在一个地方。我一直在成功地使用这个方法,直到有更好的方法出现。
这似乎是一个老bug,仍然有一些人报告问题。我建议你在ASP中创建一个问题。. NET Github repo并使用您的解决方案或另一个。