Durable Functions のエラー処理 (Azure Functions)Handling errors in Durable Functions (Azure Functions)

Durable Function のオーケストレーションはコードで実装され、プログラミング言語のエラー処理機能を使用できます。Durable Function orchestrations are implemented in code and can use the error-handling capabilities of the programming language. この点を考慮すると、エラー処理と補正をオーケストレーションに組み込むときに知っておく必要がある新しい概念は実際にはありません。With this in mind, there really aren't any new concepts you need to learn about when incorporating error handling and compensation into your orchestrations. ただし、注意する必要があるいくつかの動作があります。However, there are a few behaviors that you should be aware of.

アクティビティ関数のエラーErrors in activity functions

アクティビティ関数でスローされた例外はオーケストレーター関数に戻され、FunctionFailedException としてスローされます。Any exception that is thrown in an activity function is marshalled back to the orchestrator function and thrown as a FunctionFailedException. ニーズに合ったエラー処理と補正コードをオーケストレーター関数内に記述できます。You can write error handling and compensation code that suits your needs in the orchestrator function.

たとえば、ある口座の資金を別の口座に送金する次のオーケストレーター関数を検討します。For example, consider the following orchestrator function which transfers funds from one account to another:

#r "Microsoft.Azure.WebJobs.Extensions.DurableTask"

public static async Task Run(DurableOrchestrationContext context)
{
    var transferDetails = ctx.GetInput<TransferOperation>();

    await context.CallActivityAsync("DebitAccount",
        new
        { 
            Account = transferDetails.SourceAccount,
            Amount = transferDetails.Amount
        });

    try
    {
        await context.CallActivityAsync("CreditAccount",         
            new
            { 
                Account = transferDetails.DestinationAccount,
                Amount = transferDetails.Amount
            });
    }
    catch (Exception)
    {
        // Refund the source account.
        // Another try/catch could be used here based on the needs of the application.
        await context.CallActivityAsync("CreditAccount",         
            new
            { 
                Account = transferDetails.SourceAccount,
                Amount = transferDetails.Amount
            });
    }
}

送金先口座に対する CreditAccount 関数の呼び出しが失敗した場合、オーケストレーター関数は、資金を送金元口座に戻すことで、これを補正します。If the call to the CreditAccount function fails for the destination account, the orchestrator function compensates for this by crediting the funds back to the source account.

エラー発生時の自動再試行Automatic retry on failure

アクティビティ関数またはサブオーケストレーション関数を呼び出すときに、自動再試行ポリシーを指定できます。When you call activity functions or sub-orchestration functions you can specify an automatic retry policy. 次の例では、関数の呼び出しを最大 3 回試行し、次の再試行まで 5 秒間待機します。The following example attempts to call a function up to 3 times and waits 5 seconds between each retry:

public static async Task Run(DurableOrchestrationContext context)
{
    var retryOptions = new RetryOptions(
        firstRetryInterval: TimeSpan.FromSeconds(5),
        maxNumberOfAttempts: 3);

    await ctx.CallActivityWithRetryAsync("FlakyFunction", retryOptions, null);

    // ...
}

CallActivityWithRetryAsync API は、RetryOptions パラメーターを使用します。The CallActivityWithRetryAsync API takes a RetryOptions parameter. CallSubOrchestratorWithRetryAsync API を使用するサブオーケストレーション呼び出しは、同じ再試行ポリシーを使用できます。Sub-orchestration calls using the CallSubOrchestratorWithRetryAsync API can use these same retry policies.

自動再試行ポリシーをカスタマイズするためのいくつかのオプションがあります。There are several options for customizing the automatic retry policy. 次のオプションが含まれます。They include the following:

  • 最大試行回数: 再試行が行われる最大回数。Max number of attempts: The maximum number of retry attempts.
  • 1 回目の再試行の間隔: 1 回目の再試行を行う前の待機時間。First retry interval: The amount of time to wait before the first retry attempt.
  • バックオフ係数: バックオフの増加率を決定するために使用される係数。Backoff coefficient: The coefficient used to determine rate of increase of backoff. 既定値は 1 です。Defaults to 1.
  • 最大再試行間隔: 次の再試行を実行する前に待機する最大時間。Max retry interval: The maximum amount of time to wait in between retry attempts.
  • 再試行タイムアウト: 再試行を実行するために費やす最大時間。Retry timeout: The maximum amount of time to spend doing retries. 既定の動作は、無限の再試行です。The default behavior is to retry indefinitely.
  • カスタム: 関数呼び出しを再試行するかどうかを決定するユーザー定義のコールバックを指定できます。Custom: A user-defined callback can be specified which determines whether or not a function call should be retried.

関数のタイムアウトFunction timeouts

完了に時間がかかりすぎる場合は、オーケストレーター関数内の関数呼び出しを破棄できます。You might want to abandon a function call within an orchestrator function if it is taking too long to complete. 現時点でこれを行う適切な方法は、次の例に示すように、context.CreateTimerTask.WhenAny を使用して永続タイマーを作成することです。The proper way to do this today is by creating a durable timer using context.CreateTimer in conjunction with Task.WhenAny, as in the following example:

public static async Task<bool> Run(DurableOrchestrationContext context)
{
    TimeSpan timeout = TimeSpan.FromSeconds(30);
    DateTime deadline = context.CurrentUtcDateTime.Add(timeout);

    using (var cts = new CancellationTokenSource())
    {
        Task activityTask = context.CallActivityAsync("FlakyFunction");
        Task timeoutTask = context.CreateTimer(deadline, cts.Token);

        Task winner = await Task.WhenAny(activityTask, timeoutTask);
        if (winner == activityTask)
        {
            // success case
            cts.Cancel();
            return true;
        }
        else
        {
            // timeout case
            return false;
        }
    }
}

注意

このメカニズムは、実際には、進行中のアクティビティ関数の実行を終了するのではなく、This mechanism does not actually terminate in-progress activity function execution. オーケストレーター関数が、単に結果を無視して、次に進めるようにするだけです。Rather, it simply allows the orchestrator function to ignore the result and move on. 詳細については、タイマーに関するドキュメントをご覧ください。See the Timers documentation for more information.

ハンドルされない例外Unhandled exceptions

オーケストレーター関数がハンドルされない例外で失敗した場合、例外の詳細がログに記録され、インスタンスは Failed 状態で完了します。If an orchestrator function fails with an unhandled exception, the details of the exception are logged and the instance completes with a Failed status.

次の手順Next steps