5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【ASP.NET Web API】謎のOperationCanceledException

Posted at

とあるコンテンツをリリースした直後に以下のようなエラーがちょいちょい発生していました。

System.OperationCanceledException: 操作は取り消されました。
   場所 System.Threading.CancellationToken.ThrowIfCancellationRequested()
   場所 System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- 直前に例外がスローされた場所からのスタック トレースの終わり ---
   場所 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   場所 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   場所 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   場所 System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()
--- 直前に例外がスローされた場所からのスタック トレースの終わり ---
   場所 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   場所 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   場所 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   場所 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   場所 System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- 直前に例外がスローされた場所からのスタック トレースの終わり ---
   場所 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   場所 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   場所 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   場所 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   場所 System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()

スタックトレースにコンテンツ側のコード情報が出てなかったり、ネットで調べてもTaskベースの非同期処理がキャンセルされた時に発生するとは出てくるものの、そもそもそのコンテンツでは基本的に非同期処理を使っていなかったので、原因がよくわからない状態でした。

ただ、エラーが発生しているURLを見てみたら全部ASP.NET Web APIでの箇所しか出てなかったので、そこに絞って調べてみたら以下のページにたどり着きました。

要はAjax処理がキャンセルされた時に発生する(ASP.NET Web APIのバグ?な)ようで、独自実装したExceptionFilterAttributeに以下の処理を追加したら出なくなるようになりました。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class ApplicationErrorApiFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext?.Exception == null)
            return;

        if (actionExecutedContext.Exception is OperationCanceledException)
        {
            // HttpCode:200を返して何事もなかったようにする
            actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse();
            return;
        }

        actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
    }
}

そのコンテンツの場合はクライアントサイドでAjax処理中に他のアクションも起こせるようになっていため、↑のような処理を記述して対応せざるをえませんでしたが、サービスやアプリケーションによってはAjax処理中は他のアクションをブロックするなどの対応が必要になります。

その辺はアプリケーションの非機能要件次第なので、各担当者に確認して適した対応を行う必要があります。

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?