Erreurs
Chaque échec lève une exception. Deux classes, et un id de requête sur chaque erreur d'API.
En attraper une
from openemail import OpenEmailApiError, OpenEmailNetworkError, openemail try: openemail.emails.send({'from': sender, 'to': recipient, 'subject': subject, 'text': text})except OpenEmailApiError as error: if error.is_validation: print(error.code, error.param, error.message) if error.is_permission: print(openemail.addresses.list()) if error.is_rate_limited: print('try again in', error.retry_after_seconds, 'seconds') print(error.status, error.request_id) raiseexcept OpenEmailNetworkError as error: if error.is_timeout: print('no answer in time') raiseUn permission_error sur un envoi vient généralement de la portée d'envoi de la CLÉ (un domaine ou une adresse qui ne lui a pas été accordé) plutôt que du workspace, et c'est pourquoi l'exemple affiche les adresses depuis lesquelles addresses.list() indique que cette clé peut envoyer.
Les classes
| Classe | Quand |
|---|---|
| OpenEmailApiError | L'API a répondu, et pas par un succès. Porte message, status, type, code, param, doc_url, request_id, retry_after_seconds, fields et body. |
| OpenEmailNetworkError | Aucune réponse n'est arrivée : DNS, TLS, une connexion coupée ou le timeout. Porte cause, l'exception httpx sous-jacente, et is_timeout vaut True quand le timeout en est la raison. |
| OpenEmailError | La classe de base des deux : un seul except attrape donc chaque échec causé par l'API ou par le réseau. WebhookVerificationError, que lève verify_webhook_signature, en hérite aussi. |
| ValueError | Levée avant tout envoi : une clé manquante ou malformée, un base_url inutilisable, un identifiant destiné à du http simple, un id vide. Un mauvais http_client, ou un corps que JSON ne peut pas transporter, lève TypeError à la place. |
fields liste chaque réponse qu'un formulaire d'inscription a refusée, sous forme de key et error, et vaut None pour toute autre erreur. body conserve le JSON envoyé par l'API, ou None quand le corps n'était pas du JSON.
| Propriété | Vrai quand |
|---|---|
| is_auth | type vaut authentication_error, un 401 : aucune clé, un type d'identifiant erroné, ou une clé que nous n'avons pas émise. |
| is_permission | permission_error, un 403 : une vraie clé à laquelle manque la portée ou l'adresse From dont elle a besoin. |
| is_scope_missing | code vaut insufficient_scope, le 403 qui nomme une portée manquante. |
| is_invalid_request | invalid_request_error, un 400 : une requête qui n'a pas pu être comprise. Un message dépassant le plafond de taille revient en 422 message_too_large : c'est donc la propriété is_validation qui l'attrape. |
| is_validation | validation_error, un 422 : le schéma l'a refusée, et param nomme le champ. |
| is_not_found | not_found_error, un 404 : la ressource n'existe pas. |
| is_conflict | conflict_error, un 409 : la ressource a dépassé le stade où cette opération pouvait encore lui être appliquée. |
| is_rate_limited | rate_limit_error, un 429. retry_after_seconds contient le délai d'attente quand le serveur en a indiqué un. |
| is_server_error | status vaut 500 ou plus. Citez request_id si vous contactez le support. |
| is_retryable | status vaut 408, 429, 500, 502, 503 ou 504. |
| is_step_up_required | code vaut step_up_required, le 403 qu'un jeton d'accès OAuth reçoit avant un changement sensible tant que la personne n'a pas vérifié de code. |
La plupart des propriétés lisent type, la moitié figée de l'enveloppe. code reste un str, car l'API garantit qu'il est ouvert et additif : traitez donc un code que vous ne reconnaissez pas comme son type. Un Literal fermé ferait d'une mise à jour du SDK le prix à payer pour lire un nouveau mode d'échec.
Un corps qui n'est pas l'enveloppe d'erreur de l'API devient malgré tout une OpenEmailApiError, avec type déduit du statut et code fixé à unrecognised_response. Une réponse en succès dont le corps n'est pas du JSON en lève une également.
Annuler un appel d'AsyncOpenEmail ne lève aucune OpenEmailError. C'est l'annulation elle-même qui se propage, qu'elle survienne pendant la requête ou pendant l'attente précédant une nouvelle tentative, et rien n'est réessayé après elle.
request_id
Chaque OpenEmailApiError porte l'id de requête envoyé par le serveur, issu du corps de l'erreur ou de l'en-tête x-request-id, et c'est la seule chose qui relie votre échec à une ligne du journal du serveur. Une réponse en succès ne renvoie que le corps analysé : il n'y a donc pas d'id de requête à y lire.
str(error) se termine par le statut, le code et l'id de requête : une ligne de journal qui affiche l'exception conserve donc les trois. Une OpenEmailApiError survit aussi à la sérialisation par pickle avec tous ses champs : une erreur levée dans un processus worker parvient donc intacte au processus parent.