在 Durable Functions (Azure Functions) 中處理錯誤

Durable Function 協調流程會在程式碼中實作,且可以使用程式設計語言的內建錯誤處理功能。 將錯誤處理和補償新增至協調流程時,確實已沒有任何新的概念需要了解。 不過,有一些行為值得注意。

注意

適用於 Azure Functions 的第 4 版 Node.js 程式設計模型已正式推出。 新的 v4 模型旨在為 JavaScript 和 TypeScript 開發人員提供更靈活的直覺式體驗。 如需深入了解 v3 與 v4 之間的差異,請參閱移轉指南

在下列程式碼片段中,JavaScript (PM4) 表示程式設計模型 V4,這是新的體驗。

活動函式中的錯誤

活動函式中擲回的任何例外狀況會封送處理回到協調器函式,並以 FunctionFailedException 擲回。 您可以在協調器函式中撰寫符合需求的錯誤處理和補償程式碼。

例如,假設有下列協調器函式會從一個帳戶轉帳到另一個帳戶:

[FunctionName("TransferFunds")]
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var transferDetails = context.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
            });
    }
}

注意

先前的 C# 範例適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 DurableOrchestrationContext 而不是 IDurableOrchestrationContext。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

如果首次 CreditAccount 函式呼叫失敗,協調器函式會將款項匯回到來源帳戶,以進行彌補。

失敗時自動重試

當您呼叫活動函式或子協調流程函式時,您可以指定自動重試原則。 下列範例會嘗試呼叫函式最多 3 次,並於每次重試之間等待 5 秒鐘:

[FunctionName("TimerOrchestratorWithRetry")]
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var retryOptions = new RetryOptions(
        firstRetryInterval: TimeSpan.FromSeconds(5),
        maxNumberOfAttempts: 3);

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

    // ...
}

注意

先前的 C# 範例適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 DurableOrchestrationContext 而不是 IDurableOrchestrationContext。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

上一個範例中的活動函式呼叫會採用設定自動重試原則的參數。 自訂自動重試原則有幾個選項:

  • 嘗試次數上限:嘗試次數上限。 如果設定為 1,則不會進行重試。
  • 第一次重試間隔:第一次重試嘗試之前等候的時間量。
  • 輪詢係數:用來決定輪詢增加速率的係數。 預設值為 1。
  • 最大重試間隔:重試嘗試之間等候的最大時間量。
  • 重試逾時:花費在重試的最大時間量。 預設行為是無限期地重試。

自訂重試處理常式

使用 .NET 或 JAVA 時,您也可以選擇在程式碼中實作重試處理常式。 當宣告式重試原則不夠用於表達時,這很實用。 對於未支援自訂重試處理常式的語言,您仍然可以選擇使用迴圈、例外狀況處理及計時器來實作重試原則,以插入重試之間的延遲。

RetryOptions retryOptions = new RetryOptions(
    firstRetryInterval: TimeSpan.FromSeconds(5),
    maxNumberOfAttempts: int.MaxValue)
    {
        Handle = exception =>
        {
            // True to handle and try again, false to not handle and throw.
            if (exception is TaskFailedException failure)
            {
                // Exceptions from TaskActivities are always this type. Inspect the
                // inner Exception to get more details.
            }

            return false;
        };
    }

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

函式逾時

如果協調器函式內的函式呼叫太久才完成,您可以放棄此函式呼叫。 目前,適當的作法是使用 "any" 工作選取器來建立永久性計時器,如下列範例所示:

[FunctionName("TimerOrchestrator")]
public static async Task<bool> Run([OrchestrationTrigger] IDurableOrchestrationContext 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;
        }
    }
}

注意

先前的 C# 範例適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 DurableOrchestrationContext 而不是 IDurableOrchestrationContext。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

注意

這項機制並不會實際終止進行中的活動函式執行。 只是讓協調器函式略過結果並繼續執行。 如需詳細資訊,請參閱計時器文件。

未處理的例外狀況

如果協調器函式失敗並傳回未處理的例外狀況,例外狀況的詳細資料會記錄下來,而在執行個體會以 Failed 狀態結束。

下一步