Delen via


Fouten verwerken in Durable Functions (Azure Functions)

Durable Function-indelingen worden geïmplementeerd in code en kunnen gebruikmaken van de ingebouwde functies voor foutafhandeling van de programmeertaal. Er zijn echt geen nieuwe concepten die u moet leren om foutafhandeling en compensatie toe te voegen aan uw indelingen. Er zijn echter enkele gedragingen waar u rekening mee moet houden.

Notitie

Versie 4 van het Node.js programmeermodel voor Azure Functions is algemeen beschikbaar. Het nieuwe v4-model is ontworpen voor een flexibelere en intuïtievere ervaring voor JavaScript- en TypeScript-ontwikkelaars. Meer informatie over de verschillen tussen v3 en v4 in de migratiehandleiding.

In de volgende codefragmenten geeft JavaScript (PM4) het programmeermodel V4 aan, de nieuwe ervaring.

Fouten in activiteitsfuncties

Elke uitzondering die in een activiteitsfunctie wordt gegenereerd, wordt teruggezet naar de orchestratorfunctie en als een FunctionFailedException. U kunt foutafhandeling en compensatiecode schrijven die aansluit bij uw behoeften in de orchestrator-functie.

Denk bijvoorbeeld aan de volgende orchestratorfunctie waarmee geld van de ene rekening naar de andere wordt overboekt:

[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
            });
    }
}

Notitie

De vorige C#-voorbeelden zijn voor Durable Functions 2.x. Voor Durable Functions 1.x moet u in DurableOrchestrationContext plaats van IDurableOrchestrationContext. Zie het artikel Over Durable Functions-versies voor meer informatie over de verschillen tussen versies.

Als de eerste aanroep van de functie CreditAccount mislukt, compenseert de orchestrator-functie door het geld terug te schrijven naar de bronaccount.

Automatisch opnieuw proberen bij fout

Wanneer u activiteitsfuncties of subindelingsfuncties aanroept, kunt u een beleid voor automatisch opnieuw proberen opgeven. In het volgende voorbeeld wordt geprobeerd een functie tot drie keer aan te roepen en wacht vijf seconden tussen elke nieuwe poging:

[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);

    // ...
}

Notitie

De vorige C#-voorbeelden zijn voor Durable Functions 2.x. Voor Durable Functions 1.x moet u in DurableOrchestrationContext plaats van IDurableOrchestrationContext. Zie het artikel Over Durable Functions-versies voor meer informatie over de verschillen tussen versies.

De aanroep van de activiteitsfunctie in het vorige voorbeeld gebruikt een parameter voor het configureren van een beleid voor automatisch opnieuw proberen. Er zijn verschillende opties voor het aanpassen van het beleid voor automatisch opnieuw proberen:

  • Maximum aantal pogingen: het maximum aantal pogingen. Als deze optie is ingesteld op 1, wordt het niet opnieuw geprobeerd.
  • Eerste interval voor opnieuw proberen: de hoeveelheid tijd die moet worden gewacht voor de eerste nieuwe poging.
  • Uitstelcoëfficiënt: de coëfficiënt die wordt gebruikt voor het bepalen van de snelheid van toename van de uitstel. Standaardwaarde is 1.
  • Maximuminterval voor opnieuw proberen: de maximale hoeveelheid tijd die moet worden gewacht tussen nieuwe pogingen.
  • Time-out voor opnieuw proberen: de maximale hoeveelheid tijd die moet worden besteed aan nieuwe pogingen. Het standaardgedrag is om het voor onbepaalde tijd opnieuw te proberen.

Aangepaste handlers voor opnieuw proberen

Wanneer u .NET of Java gebruikt, hebt u ook de mogelijkheid om handlers voor opnieuw proberen in code te implementeren. Dit is handig wanneer beleid voor declaratieve nieuwe pogingen niet expressief genoeg is. Voor talen die geen aangepaste handlers voor nieuwe pogingen ondersteunen, hebt u nog steeds de mogelijkheid om beleid voor opnieuw proberen te implementeren met behulp van lussen, afhandeling van uitzonderingen en timers voor het injecteren van vertragingen tussen nieuwe pogingen.

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);

Time-outs voor functies

Mogelijk wilt u een functieaanroep binnen een orchestratorfunctie afbreken als het te lang duurt voordat deze is voltooid. De juiste manier om dit vandaag te doen is door een duurzame timer te maken met een 'any'-taakkiezer, zoals in het volgende voorbeeld:

[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;
        }
    }
}

Notitie

De vorige C#-voorbeelden zijn voor Durable Functions 2.x. Voor Durable Functions 1.x moet u in DurableOrchestrationContext plaats van IDurableOrchestrationContext. Zie het artikel Over Durable Functions-versies voor meer informatie over de verschillen tussen versies.

Notitie

Dit mechanisme beëindigt de uitvoering van de actieve activiteitsfunctie niet. In plaats daarvan kan de orchestratorfunctie het resultaat negeren en verdergaan. Zie de documentatie voor timers voor meer informatie.

Onverwerkte uitzonderingen

Als een orchestratorfunctie mislukt met een niet-verwerkte uitzondering, worden de details van de uitzondering geregistreerd en wordt de instantie voltooid met een Failed status.

Volgende stappen