Help us understand the problem. What is going on with this article?

【ASP.NET Web API】謎のOperationCanceledException

More than 3 years have passed since last update.

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

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での箇所しか出てなかったので、そこに絞って調べてみたら以下のページにたどり着きました。

http://stackoverflow.com/questions/22157596/asp-net-web-api-operationcanceledexception-when-browser-cancels-the-request

要は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処理中は他のアクションをブロックするなどの対応が必要になります。

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした