Les erreurs de resolver arrivent avec HTTP 200
C’est la chose la plus importante à savoir avant d’écrire votre gestion des erreurs. Conformément à la spécification GraphQL over HTTP, une requête qui atteint nos resolvers renvoie HTTP 200 même lorsqu’une opération a échoué. L’échec est signalé dans le corps de la réponse, et non par le code de statut. Cette vérification ne fonctionne donc pas :Content-Type non pris en charge, ont un corps vide ; vérifiez donc que la réponse est au format JSON avant de l’analyser :
- Une requête mal formée renvoie un statut d’erreur : HTTP 400 pour un JSON invalide ou une
querymanquante, 413 pour un corps de plus de 64 Ko, 405 pour une méthode autre quePOST, et 415 pour unContent-Typenon pris en charge. - Une query non valide pour le schéma renvoie HTTP 400 uniquement si votre requête envoie
Accept: application/graphql-response+json. Cela couvre une erreur de syntaxe, un champ inconnu, un mauvais type d’argument, une valeur d’enum invalide et une query dépassant les limites de requête. Si vous envoyezAccept: application/json, ou aucun en-têteAccept, la même erreur renvoie HTTP 200. Dans les deux cas, le corps contient un tableauerrorset pas dedata.
errors.
La structure d’une erreur
Chaque erreur de resolver transporte son statut d’API de type HTTP dansextensions :
message: une description lisible par un humain. Nous retirons les API Keys et autres identifiants des messages d’erreur des resolvers, mais une erreur portant sur une valeur que vous avez envoyée, comme une variable du mauvais type, peut reprendre cette valeur. Considérezmessagecomme potentiellement sensible avant de le journaliser.path: le champ de votre query qui a échoué. Avec plusieurs champs dans une requête, c’est ainsi que vous savez lequel.extensions.status: le statut HTTP que l’appel REST équivalent aurait renvoyé. Basez votre logique sur cette valeur.extensions.code: le code d’erreur numérique Ayrshare, lorsque le point de terminaison sous-jacent en fournit un.extensions.retryAfter: présent sur les 429 de quota ou de limite de débit en amont lorsqu’un délai avant nouvelle tentative est disponible. Il n’est pas présent sur le 429 du budget de dispatch par requête.
extensions.code avec la référence des codes d’erreur, ou transmettez-le à explainError.
Succès partiel
Si une requête demande plusieurs choses et que seules certaines réussissent, vous obtenez à la foisdata et errors :
history a réussi et ses données sont utilisables. Seul analytics doit être relancé. Ne rejetez pas toute la réponse parce que errors est présent : vous jetteriez des données qui vous ont déjà été facturées.
Succès partiel sur les publications multi-réseaux
Une publication sur plusieurs réseaux peut réussir sur certains et échouer sur d’autres. Ce cas n’est pas signalé comme une erreur GraphQL, car l’opération elle-même a fonctionné : elle a fait exactement ce que vous avez demandé et vous indique ce qui s’est passé. Le résultat distingue les trois issues :postIds: les réseaux sur lesquels la publication a réussi, avec les URL des publications. Uniquement les succès.errors: les réseaux qui ont échoué, avec la raison.blocked: les réseaux arrêtés avant toute tentative, par exemple par le disjoncteur par réseau après des échecs déterministes répétés. Ils sont distincts des tentatives auprès du fournisseur qui ont renvoyé des erreurs.
status vaut "error" si au moins un réseau a échoué ; ce n’est donc pas un signal fiable indiquant que rien n’a été publié. Lisez postIds pour savoir ce qui l’a été.
Nouvelles tentatives
L’API GraphQL ne relance jamais automatiquement. Si une requête échoue, rien n’a été retenté silencieusement en votre nom. C’est surtout important pour les mutations.createPost expose idempotencyKey : générez une clé unique avant la première tentative, puis réutilisez la même clé et un payload identique pour chaque nouvelle tentative. Une nouvelle tentative réglée rejoue le résultat d’origine au lieu de répéter l’écriture. Ne passez pas à une nouvelle clé après une réponse ambiguë.
boostFacebookPost et instagramBoostPost acceptent également une idempotencyKey, et elle protège de l’argent réel. Une nouvelle tentative avec la même clé et les mêmes arguments renvoie le résultat d’origine, marqué idempotentReplayed: true, au lieu de créer et de payer une seconde publicité. Une clé couvre l’ensemble de votre compte sur les deux plateformes Meta ; ne réutilisez donc jamais la clé d’un boost Facebook pour un boost Instagram.
Lorsqu’une clé est refusée, extensions.status vous indique pourquoi. createPost renvoie 409 tant que la première tentative est encore en cours de traitement ; attendez alors et réessayez avec la même clé. Il renvoie 400 lorsque le payload diffère de celui de la première tentative. Les mutations de boost renvoient 409 dans les deux cas, ainsi que lorsque la clé a été utilisée pour un boost sur l’autre plateforme.
Les autres écritures, comme addComment, n’ont pas de clé d’idempotence. Si leur réponse est perdue, vérifiez l’état du réseau social ou de l’API avant de décider si une nouvelle tentative est sans risque.
Deux limites différentes renvoient toutes deux 429, et elles nécessitent un traitement différent. Le budget de dispatch ne rejette des champs racine qu’une fois que cinq appels API ont déjà démarré dans la même requête, et son message commence par Query exceeds the per-request dispatch budget : répartissez ces champs dans des requêtes de cinq au maximum, sans avoir besoin d’attendre. Tout autre 429 correspond à une limite de débit ou à un quota : attendez extensions.retryAfter secondes lorsqu’il est présent, sinon espacez vos tentatives avant de réessayer, et ne relancez que les champs qui ont échoué. Pour un 5xx sur une lecture, réessayer est sans risque, à une exception près : generatePost est une query, mais une nouvelle tentative rappelle le générateur IA, compte comme un appel API supplémentaire et renvoie un texte différent. Pour un 5xx sur une écriture sans idempotence, vérifiez si elle a pris effet avant de réessayer.
Statuts courants
Les erreurs levées par GraphQL lui-même avant l’exécution, comme un champ inconnu, un mauvais type d’argument ou une valeur d’enum invalide, n’ont pas d’
extensions.status. Elles renvoient HTTP 400 ou 200 selon votre en-tête Accept, comme décrit ci-dessus. Elles signifient que la query elle-même est incorrecte, et aucun appel API n’a été effectué ni facturé.