代码演示问题:

  • 假设测试对象是一个真实的实现,例如数据库调用。
  • documentation for Web API states 表示未处理的异常将在允许您处理它们的全局处理程序中捕获。
  • 如果我用一个 ExceptionFilter 替换 MyErrorHandler 这确实有效,除了我正在使用的代码库使用处理程序,因为错误逻辑是一个交叉问题,无论错误来自哪里都是相同的。
  • 如果抛出的异常类型不是 TaskCancelledException,它会按预期调用处理程序。
  • 我也尝试过最新版本的 Web API (5.2.3)。
  • 唯一的解决方法是在可以抛出此类异常的任何地方添加一个 try/catch 块,不用说这是痛苦的,我希望避免使用处理程序。

  • 鉴于这不是我的代码,我讨厌将其称为错误,但经过数小时的尝试后,它开始有这种感觉。
    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 位于一处。我正在成功地使用它作为解决方案,直到出现更好的东西。

    关于c# - Web API 2 - 全局异常处理程序不适用于 TaskCancellation,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32566071/

    10-17 00:49