Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Erreurs et nouvelles tentatives dans le cloud

Après cette leçon: Je peux dire quelle erreur il faut réessayer et laquelle il faut corriger.

Leçon de 55 minAucune commande

Certaines erreurs passent toutes seules

Un service cloud répond à chaque appel, et parfois la réponse est une erreur. Un code d’erreur dit de quelle sorte elle est.

Un bucket S3 absent reste absent si vous redemandez. Une table DynamoDB occupée peut répondre une seconde plus tard. Cette leçon apprend à distinguer les deux et à réessayer la bonne.

À la fin de cette leçon

Remarque

Je peux dire quelle erreur il faut réessayer et laquelle il faut corriger.

Mots-clés

MotCe que ça veut direExemple
Code d’erreurun nom court pour ce qui s’est mal passéNoSuchKey
Code de statutun nombre qui range une réponse dans une famille404
Limitation de débitun service qui refuse des appels parce que vous en avez trop envoyéthrottling
Nouvelle tentativeenvoyer de nouveau le même appel
Attente croissanteattendre plus longtemps avant chaque nouvelle tentativebackoff
Gigueune part au hasard de l’attente, pour que les appelants ne bougent pas ensemblejitter

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Une erreur a un code et un statut

Quand un appel échoue, boto3 vous donne une erreur. Elle contient un code de statut, comme 404, et un code d’erreur, comme NoSuchKey.

Testez le code d’erreur et le statut. Ne testez pas le message : sa formulation peut changer d’un service à l’autre, et celle de l’émulateur diffère parfois de la vraie.

Exemple : des erreurs lues dans des réponses capturées

AppelCodeStatutRéessayer ?
get_object, clé absenteNoSuchKey404Non, corrigez la clé
head_object, clé absente404404Non, il n’y a pas de corps à lire
list_objects_v2, bucket absentNoSuchBucket404Non, créez le bucket
put_item, condition fausseConditionalCheckFailedException400Non, la réponse est la réponse
query, mauvais nom de cléValidationException400Non, corrigez l’appel
send_message, file absenteAWS.SimpleQueueService.NonExistentQueue400Non, créez la file

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Exécutez : lire le code et le statut

Code: python
reponses = [
    {"error": {"Code": "NoSuchKey", "Message": "Absente.", "HTTPStatusCode": 404}},
    {"error": {"Code": "ConditionalCheckFailedException", "Message": "Non.", "HTTPStatusCode": 400}},
    {"error": {"Code": "InternalServerError", "Message": "Oups.", "HTTPStatusCode": 500}},
    {"Items": []},
]
for reponse in reponses:
    if "error" not in reponse:
        print("réussi")
    else:
        erreur = reponse["error"]
        print(erreur["Code"], erreur["HTTPStatusCode"])

Réessayer ce qui peut marcher la prochaine fois

Certaines erreurs disent « pas maintenant ». Une limitation de débit veut dire que vous avez envoyé trop d’appels. Un statut de 500 ou plus veut dire que le service a eu une panne. Les deux peuvent passer si vous attendez.

D’autres erreurs disent « pas cet appel ». Votre appel était faux, donc le même appel échoue à chaque fois. Corrigez-le plutôt.

Erreur fréquente

Attention

Beaucoup réessaient toutes les erreurs, par prudence. Une mauvaise clé échoue alors cinq fois et vous fait perdre du temps à attendre pour rien. Ne réessayez que les limitations de débit et les pannes du service. Corrigez toutes les autres, car le même appel donne la même réponse.

Exécutez : trier réessayer ou corriger

Code: python
# Les codes de limitation sont ceux de la documentation, non capturés ici.
LIMITATIONS = ["ThrottlingException", "ProvisionedThroughputExceededException", "SlowDown"]

def vaut_un_nouvel_essai(erreur):
    if erreur["HTTPStatusCode"] >= 500:
        return True
    return erreur["Code"] in LIMITATIONS

erreurs = [
    {"Code": "NoSuchKey", "HTTPStatusCode": 404},
    {"Code": "SlowDown", "HTTPStatusCode": 503},
    {"Code": "ThrottlingException", "HTTPStatusCode": 400},
    {"Code": "ValidationException", "HTTPStatusCode": 400},
]
for erreur in erreurs:
    print(erreur["Code"], vaut_un_nouvel_essai(erreur))
# Ajoutez "RequestLimitExceeded" à LIMITATIONS et testez-le.

L’attente croît à chaque essai

Si un service est occupé, réessayer une milliseconde plus tard le rend plus occupé encore. Attendez donc, et attendez plus longtemps après chaque échec. Doubler l’attente est courant. Fixez un plafond pour que l’attente ne dépasse jamais une limite.

Ajoutez maintenant de la gigue : attendez une part au hasard de ce temps. Sans elle, cent appelants se réveillent ensemble et échouent ensemble de nouveau.

Exemple travaillé : le plafond de chaque attente

EssaiDoubléAvec un plafond de 8Attente si le tirage est 0,5
10,5 seconde0,50,25
21 seconde10,5
32 secondes21
44 secondes42
58 secondes84
616 secondes84

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Exécutez : une attente que l’on peut tester

Code: python
# tirage est un nombre de 0 à 1. Un vrai appelant passe random.random().
# Un test passe un nombre fixe, donc la réponse ne change jamais.
def delai_attente(tentative, base, plafond, tirage):
    maximum = min(plafond, base * 2 ** (tentative - 1))
    return maximum * tirage

for tentative in range(1, 7):
    print(tentative, delai_attente(tentative, 0.5, 8, 1.0), delai_attente(tentative, 0.5, 8, 0.5))
# Passez le plafond de 8 à 2. Quels essais changent ?

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.