Gestion des erreurs et nouvelles tentatives dans Azure Functions

La gestion des erreurs dans Azure Functions est importante pour vous aider à éviter des pertes de données et des événements manqués, ainsi que pour superviser l’intégrité de votre application. Il s’agit également d’un point important permettant de comprendre les comportements de nouvelle tentative des déclencheurs basés sur des événements.

Cet article décrit les stratégies générales de gestion des erreurs et les stratégies de nouvelles tentatives disponibles.

Important

La prise en charge préliminaire des stratégies de nouvelles tentatives pour certains déclencheurs a été supprimée en décembre 2022. Les stratégies de nouvelles tentatives pour les déclencheurs pris en charge sont désormais en disponibilité générale (GA). Pour obtenir la liste des extensions qui prennent actuellement en charge les stratégies de nouvelles tentatives, consultez la section Nouvelles tentatives.

Gestion des erreurs

Les erreurs qui se produisent dans une fonction Azure peuvent avoir les causes suivantes :

  • Utilisation de déclencheurs et liaisons Functions intégrés.
  • Appels aux API des services Azure sous-jacents.
  • Appels aux points de terminaison REST.
  • Appels aux bibliothèques clientes, aux packages ou aux API tierces.

Les bonnes pratiques de gestion des erreurs sont importantes pour éviter de perdre des données ou de manquer des messages. Ce tableau décrit certaines pratiques de gestion des erreurs recommandées et propose des liens vers des informations complémentaires.

Recommandation Détails
Activer Application Insights Azure Functions s’intègre à Application Insights pour collecter des données d’erreur, des données de performances et des journaux d’exécution. Vous devez utiliser Application Insights pour découvrir et mieux comprendre les erreurs qui se produisent dans vos exécutions de fonction. Pour en savoir plus, consultez Surveiller l’exécution des fonctions Azure.
Utiliser la gestion structurée des erreurs La capture et la journalisation des erreurs sont essentielles pour superviser l’intégrité de votre application. Le niveau le plus élevé de tout code de fonction doit inclure un bloc try/catch. Dans le bloc catch, vous pouvez capturer et journaliser les erreurs. Pour plus d’informations sur les erreurs susceptibles d’être déclenchées par des liaisons, consultez Codes d’erreur de liaison. Selon la stratégie de nouvelles tentatives spécifique que vous utilisez, vous pouvez également lever une nouvelle exception pour réexécuter la fonction.
Planifier votre stratégie de nouvelles tentatives Plusieurs extensions de liaisons Functions offrent une prise en charge intégrée des nouvelles tentatives ; d’autres vous permettent de définir des stratégies de nouvelles tentatives, qui sont implémentées par le runtime Functions. Pour les déclencheurs qui n’offrent pas de comportements de nouvelles tentatives, envisagez d’implémenter votre propre schéma de nouvelles tentatives. Pour plus d’informations, consultez Nouvelles tentatives.
Concevoir en ayant en vue l’idempotence L’occurrence d’erreurs lors du traitement des données peut être problématique pour vos fonctions, en particulier lors du traitement des messages. Il est important de prendre en compte ce qui se passe quand l’erreur se produit et d’éviter le traitement en double. Pour plus d'informations, consultez Conception d’Azure Functions pour une entrée identique.

Nouvelle tentatives

Deux types de nouvelles tentatives sont disponibles pour vos fonctions :

  • Comportements de nouvelle tentative intégrés d’extensions de déclencheur individuelles
  • Stratégies relatives aux nouvelles tentatives fournies par le runtime Functions

Le tableau suivant indique quels déclencheurs prennent en charge les nouvelles tentatives et où le comportement de nouvelle tentative est configuré. Il fournit également des liens pour obtenir des informations supplémentaires sur les erreurs provenant des services sous-jacents.

Déclencheur/liaison Source de nouvelle tentative Configuration
Azure Cosmos DB Stratégies de nouvelle tentative Au niveau de la fonction
Stockage Blob Extension de liaison host.json
Event Grid Extension de liaison Abonnement à un événement
Event Hubs Stratégies de nouvelle tentative Au niveau de la fonction
Kafka Stratégies de nouvelle tentative Au niveau de la fonction
Stockage File d’attente Extension de liaison host.json
RabbitMQ Extension de liaison File d’attente de lettres mortes
Service Bus Extension de liaison host.json*
Minuterie Stratégies de nouvelle tentative Au niveau de la fonction

*Nécessite la version 5.x de l’extension Azure Service Bus. Dans les versions antérieures de l’extension, les comportements de nouvelles tentatives sont implémentés par la file d’attente de lettres mortes Service Bus.

Stratégies de nouvelle tentative

Azure Functions vous permet de définir des stratégies de nouvelles tentatives pour des types de déclencheurs spécifiques, qui sont appliquées par le runtime. Voici les types de déclencheurs qui prennent actuellement en charge les stratégies de nouvelles tentatives :

La prise en charge des nouvelles tentatives est identique pour les modèles de programmation Python v1 et v2.

Les stratégies de nouvelles tentatives ne sont pas prises en charge dans la version 1.x du runtime Functions.

La stratégie de nouvelles tentatives indique au runtime de réexécuter une exécution ayant échoué jusqu’à ce que l’achèvement réussi se produise ou que le nombre maximal de nouvelles tentatives soit atteint.

Une stratégie de nouvelles tentatives est évaluée quand une fonction exécutée par un type de déclencheur pris en charge lève une exception non interceptée. La meilleure pratique consiste à intercepter toutes les exceptions dans votre code et à lever de nouvelles exceptions pour les erreurs qui doivent donner lieu à une nouvelle tentative.

Important

Les points de contrôle Event Hubs ne sont pas écrits tant que la stratégie de nouvelles tentatives n’a pas abouti pour l’exécution. Du fait de ce comportement, la progression sur la partition spécifique est suspendue tant que le traitement du lot actuel ne s’est pas terminé.

La version 5.x de l’extension Event Hubs prend en charge d’autres fonctionnalités de nouvelles tentatives pour les interactions entre l’hôte Functions et le hub d’événements. Pour plus d’informations, consultez clientRetryOptions dans les informations de référence sur le fichier host.json Event Hubs.

Stratégie de nouvelle tentative

Vous pouvez configurer deux stratégies de nouvelles tentatives prises en charge par la stratégie :

Un laps de temps spécifié est autorisé à s’écouler entre chaque nouvelle tentative.

Dans le cadre d’un plan Consommation, seul le temps d’exécution de votre code de fonction vous êtes facturé. Vous n’êtes pas facturé sur le temps d’attente entre les différentes exécutions, dans aucune de ces deux stratégies de nouvelles tentatives.

Nombre maximal de nouvelles tentatives

Vous pouvez configurer le nombre maximal de nouvelles tentatives d’exécution de fonction avant un éventuel échec. Le nombre actuel de nouvelles tentatives est stocké dans la mémoire de l’instance.

Il est possible qu’un échec d’instance se produise entre deux nouvelles tentatives. Quand une instance échoue durant une stratégie de nouvelles tentatives, le nombre de nouvelles tentatives est perdu. En cas d’échec d’instance, le déclencheur Event Hubs peut reprendre le traitement et retenter le lot sur une nouvelle instance, le nombre de nouvelles tentatives étant réinitialisé à zéro. Le déclencheur de minuteur ne reprend pas sur une nouvelle instance.

Ce comportement signifie que le nombre maximal de nouvelles tentatives correspond à l’effort optimal. Dans certains cas rares, le nombre de nouvelles tentatives d’exécution peut dépasser le nombre maximal demandé. Pour les déclencheurs de retardateur, les nouvelles tentatives peuvent être inférieures au nombre maximal demandé.

Exemples de nouvelle tentative

Des exemples sont fournis pour les stratégies de délai fixe et de backoff exponentiel. Pour voir des exemples concernant une stratégie spécifique, vous devez d’abord sélectionner cette stratégie dans l’onglet précédent.

Les nouvelles tentatives au niveau de la fonction sont prises en charge avec les packages NuGet suivants :

[Function(nameof(TimerFunction))]
[FixedDelayRetry(5, "00:00:10")]
public static void Run([TimerTrigger("0 */5 * * * *")] TimerInfo timerInfo,
    FunctionContext context)
{
    var logger = context.GetLogger(nameof(TimerFunction));
    logger.LogInformation($"Function Ran. Next timer schedule = {timerInfo.ScheduleStatus.Next}");
}
Propriété Description
MaxRetryCount Obligatoire. Nombre maximal de nouvelles tentatives autorisées par exécution de fonction. -1 signifie qu’il faut effectuer ces nouvelles tentatives indéfiniment.
DelayInterval Délai utilisé entre les nouvelles tentatives. Spécifiez-le sous forme de chaîne au format HH:mm:ss.

Voici un exemple de stratégie de nouvelles tentatives définie dans le fichier function.json :

{
    "disabled": false,
    "bindings": [
        {
            ....
        }
    ],
    "retry": {
        "strategy": "fixedDelay",
        "maxRetryCount": 4,
        "delayInterval": "00:00:10"
    }
}

Vous pouvez définir ces propriétés dans les définitions de stratégie de nouvelles tentatives :

Propriété Description
stratégie Obligatoire. Stratégie de nouvelle tentative à utiliser. Les valeurs valides sont fixedDelay ou exponentialBackoff.
maxRetryCount Obligatoire. Nombre maximal de nouvelles tentatives autorisées par exécution de fonction. -1 signifie qu’il faut effectuer ces nouvelles tentatives indéfiniment.
delayInterval Délai utilisé entre les nouvelles tentatives quand vous utilisez une stratégie fixedDelay. Spécifiez-le sous forme de chaîne au format HH:mm:ss.
minimumInterval Délai minimal de nouvelle tentative quand vous utilisez une stratégie exponentialBackoff. Spécifiez-le sous forme de chaîne au format HH:mm:ss.
maximumInterval Délai maximal de nouvelle tentative quand vous utilisez une stratégie exponentialBackoff. Spécifiez-le sous forme de chaîne au format HH:mm:ss.

La façon dont vous définissez la stratégie de nouvelles tentatives pour le déclencheur dépend de votre version de Node.js.

Voici un exemple de fonction de déclencheur du retardateur qui utilise une stratégie de nouvelles tentatives à délai fixe :

const { app } = require('@azure/functions');

app.timer('timerTriggerWithRetry', {
    schedule: '0 */5 * * * *',
    retry: {
        strategy: 'fixedDelay',
        delayInterval: {
            seconds: 10,
        },
        maxRetryCount: 4,
    },
    handler: (myTimer, context) => {
        if (context.retryContext?.retryCount < 2) {
            throw new Error('Retry!');
        } else {
            context.log('Timer function processed request.');
        }
    },
});

La façon dont vous définissez la stratégie de nouvelles tentatives pour le déclencheur dépend de votre version de Node.js.

Voici un exemple de fonction de déclencheur du retardateur qui utilise une stratégie de nouvelles tentatives à délai fixe :

import { app, InvocationContext, Timer } from '@azure/functions';

export async function timerTriggerWithRetry(myTimer: Timer, context: InvocationContext): Promise<void> {
    if (context.retryContext?.retryCount < 2) {
        throw new Error('Retry!');
    } else {
        context.log('Timer function processed request.');
    }
}

app.timer('timerTriggerWithRetry', {
    schedule: '0 */5 * * * *',
    retry: {
        strategy: 'fixedDelay',
        delayInterval: {
            seconds: 10,
        },
        maxRetryCount: 4,
    },
    handler: timerTriggerWithRetry,
});

Vous pouvez définir ces propriétés dans les définitions de stratégie de nouvelles tentatives :

Propriété Description
stratégie Obligatoire. Stratégie de nouvelle tentative à utiliser. Les valeurs valides sont fixedDelay ou exponentialBackoff.
maxRetryCount Obligatoire. Nombre maximal de nouvelles tentatives autorisées par exécution de fonction. -1 signifie qu’il faut effectuer ces nouvelles tentatives indéfiniment.
delayInterval Délai utilisé entre les nouvelles tentatives quand vous utilisez une stratégie fixedDelay. Spécifiez-le sous forme de chaîne au format HH:mm:ss.
minimumInterval Délai minimal de nouvelle tentative quand vous utilisez une stratégie exponentialBackoff. Spécifiez-le sous forme de chaîne au format HH:mm:ss.
maximumInterval Délai maximal de nouvelle tentative quand vous utilisez une stratégie exponentialBackoff. Spécifiez-le sous forme de chaîne au format HH:mm:ss.

Voici un exemple de fonction de déclencheur du retardateur qui utilise une stratégie de nouvelles tentatives à délai fixe :

from azure.functions import FunctionApp, TimerRequest, Context, AuthLevel
import logging

app = FunctionApp(http_auth_level=AuthLevel.ANONYMOUS)


@app.timer_trigger(schedule="*/1 * * * * *", arg_name="mytimer",
                   run_on_startup=False,
                   use_monitor=False)
@app.retry(strategy="fixed_delay", max_retry_count="3",
           delay_interval="00:00:01")
def mytimer(mytimer: TimerRequest, context: Context) -> None:
    logging.info(f'Current retry count: {context.retry_context.retry_count}')

    if context.retry_context.retry_count == \
            context.retry_context.max_retry_count:
        logging.info(
            f"Max retries of {context.retry_context.max_retry_count} for "
            f"function {context.function_name} has been reached")
    else:
        raise Exception("This is a retryable exception")

Vous pouvez définir ces propriétés dans les définitions de stratégie de nouvelles tentatives :

Propriété Description
stratégie Obligatoire. Stratégie de nouvelle tentative à utiliser. Les valeurs valides sont fixed_delay ou exponential_backoff.
max_retry_count Obligatoire. Nombre maximal de nouvelles tentatives autorisées par exécution de fonction. -1 signifie qu’il faut effectuer ces nouvelles tentatives indéfiniment.
delay_interval Délai utilisé entre les nouvelles tentatives quand vous utilisez une stratégie fixed_delay. Spécifiez-le sous forme de chaîne au format HH:mm:ss.
minimum_interval Délai minimal de nouvelle tentative quand vous utilisez une stratégie exponential_backoff. Spécifiez-le sous forme de chaîne au format HH:mm:ss.
maximum_interval Délai maximal de nouvelle tentative quand vous utilisez une stratégie exponential_backoff. Spécifiez-le sous forme de chaîne au format HH:mm:ss.
@FunctionName("TimerTriggerJava1")
@FixedDelayRetry(maxRetryCount = 4, delayInterval = "00:00:10")
public void run(
    @TimerTrigger(name = "timerInfo", schedule = "0 */5 * * * *") String timerInfo,
    final ExecutionContext context
) {
    context.getLogger().info("Java Timer trigger function executed at: " + LocalDateTime.now());
}

Codes d’erreur de liaison

Lors de l’intégration aux services Azure, vous pouvez rencontrer des erreurs provenant des API des services sous-jacents. Les informations relatives aux erreurs spécifiques à la liaison sont disponibles dans les sections « Exceptions et codes de retour » des articles suivants :

Étapes suivantes