Ce chapitre les principaux aspects du modèle d'erreur pour les API Google. Il fournit également des conseils généraux aux développeurs sur la manière de générer et de gérer correctement les erreurs.
Les API Google utilisent un modèle d'erreur simple indépendant du protocole, qui nous permet d'offrir une expérience cohérente entre différentes API, différents protocoles d'API (tels que gRPC ou HTTP) et différents contextes d'erreur (par exemple, erreurs asynchrones, par lots ou de workflow).
Modèle d'erreur
Le modèle d'erreur pour les API Google est défini de manière logique par google.rpc.Status
, dont une instance est renvoyée au client lorsqu'une erreur d'API se produit. L'extrait de code suivant montre la conception générale du modèle d'erreur :
package google.rpc;
// The `Status` type defines a logical error model that is suitable for
// different programming environments, including REST APIs and RPC APIs.
message Status {
// A simple error code that can be easily handled by the client. The
// actual error code is defined by `google.rpc.Code`.
int32 code = 1;
// A developer-facing human-readable error message in English. It should
// both explain the error and offer an actionable resolution to it.
string message = 2;
// Additional error information that the client code can use to handle
// the error, such as retry info or a help link.
repeated google.protobuf.Any details = 3;
}
Étant donné que la plupart des API Google utilisent une conception d'API axée sur les ressources, la gestion des erreurs suit le même principe de conception en utilisant un petit ensemble d'erreurs standards avec un grand nombre de ressources. Par exemple, au lieu de définir différents types d'erreurs "introuvables", le serveur utilise un code d'erreur google.rpc.Code.NOT_FOUND
standard et indique au client quelle ressource spécifique est introuvable. Le plus petit espace d'erreur réduit la complexité de la documentation, offre de meilleurs mappages idiomatiques dans les bibliothèques clientes et réduit la complexité de la logique du client tout en ne limitant pas l'inclusion d'informations exploitables.
Codes d'erreur
Les API Google doivent utiliser les codes d'erreur canoniques définis par google.rpc.Code
.
Les API individuelles doivent éviter de définir des codes d'erreur supplémentaires, car il est très peu probable que les développeurs écrivent une logique pour gérer un grand nombre de codes d'erreur. À titre de référence, gérer en moyenne trois codes d'erreur par appel d'API signifierait que la plupart de la logique d'application ne concernerait que la gestion des exceptions, ce qui ne serait pas une bonne expérience pour les développeurs.
Messages d'erreur
Le message d'erreur devrait aider les utilisateurs à comprendre et résoudre l'erreur d'API facilement et rapidement. En général, tenez compte des instructions suivantes lors de la rédaction des messages d'erreur :
- Ne partez pas du principe que l'utilisateur est un expert de votre API. Ces utilisateurs peuvent être des développeurs clients, des responsables des opérations, du personnel informatique ou des utilisateurs finaux d'applications.
- Ne partez pas du principe que l'utilisateur connaît la mise en œuvre de votre service ou qu'il connaît le contexte des erreurs (tel que l'analyse du journal).
- Dans la mesure du possible, les messages d'erreur doivent être construits de manière à ce qu'un utilisateur technique (mais pas nécessairement un développeur de votre API) puisse répondre à l'erreur et la corriger.
- Veillez à rédiger un message d'erreur concis. Si nécessaire, fournissez un lien permettant à un lecteur en difficulté de poser des questions, de faire des commentaires ou d’obtenir plus d’informations qui ne correspondent pas parfaitement à un message d’erreur. Sinon, utilisez le champ de détails pour développer.
Informations relatives à l'erreur
Les API Google définissent un ensemble de charges utiles d'erreur standard pour les informations relatives à l'erreur, que vous pouvez trouver dans google/rpc/error_details.proto. Elles couvrent les besoins les plus courants d'erreurs d'API, tels que les échecs de quota et les paramètres non valides. À l'instar des codes d'erreur, les développeurs doivent utiliser ces charges utiles standards dès que possible.
Certains types de détails d'erreur supplémentaires ne doivent être introduits que s'ils peuvent aider le code d'application à gérer les erreurs. Si les informations relatives à l'erreur ne peuvent être traitées que par des humains, utilisez le contenu du message d'erreur et laissez les développeurs le gérer manuellement plutôt que d'introduire des types de détails d'erreur supplémentaires.
Voici quelques exemples de charges utiles error_details
:
ErrorInfo
fournit des informations sur les erreurs structurées qui sont à la fois stables et extensibles.RetryInfo
: décrit quand les clients peuvent réessayer une requête ayant échoué. Elle peut être renvoyée dansCode.UNAVAILABLE
ouCode.ABORTED
.QuotaFailure
: décrit comment une vérification de quota a échoué. Elle peut être renvoyée dansCode.RESOURCE_EXHAUSTED
.BadRequest
: décrit les violations dans une requête client. Elle peut être renvoyée dansCode.INVALID_ARGUMENT
.
Information sur l'erreur
ErrorInfo
est un type particulier de charge utile d'erreur. Elle fournit des informations d'erreur stables et extensibles dont les utilisateurs et les applications peuvent dépendre.
Chaque ErrorInfo
comporte trois informations: un domaine d'erreur, un motif d'erreur et un ensemble de métadonnées d'erreur, comme cet exemple.
Pour en savoir plus, consultez la définition de ErrorInfo
.
Pour les API Google, le domaine d'erreur principal est googleapis.com
, et les motifs d'erreur correspondants sont définis par l'énumération google.api.ErrorReason
.
Pour plus d'informations, consultez la définition google.api.ErrorReason
.
Localisation des erreurs
Le champ message
dans google.rpc.Status
est destiné aux développeurs et doit être en anglais.
Si un message d'erreur adressé à l'utilisateur est nécessaire, utilisez google.rpc.LocalizedMessage
en tant que champ de détails. Bien que le champ de message dans google.rpc.LocalizedMessage
puisse être localisé, assurez-vous que ce même champ dans google.rpc.Status
est en anglais.
Par défaut, le service d'API doit utiliser les paramètres régionaux ou l'en-tête Accept-Language
de l'utilisateur authentifié, ou le paramètre language_code
dans la requête pour déterminer la langue de la localisation.
Mappage des erreurs
Les API Google sont accessibles dans différents environnements de programmation. Chaque environnement dispose généralement de sa propre façon de traiter les erreurs. Les sections suivantes expliquent comment le modèle d'erreur est mappé dans les environnements couramment utilisés.
Mappage HTTP
Bien que les messages proto3 aient un codage JSON natif, la plate-forme d'API Google utilise un schéma d'erreur différent pour les API HTTP JSON de Google pour des raisons de rétrocompatibilité.
Schéma :
// This message defines the error schema for Google's JSON HTTP APIs.
message Error {
// Deprecated. This message is only used by error format v1.
message ErrorProto {}
// This message has the same semantics as `google.rpc.Status`. It uses HTTP
// status code instead of gRPC status code. It has extra fields `status` and
// `errors` for backward compatibility with [Google API Client
// Libraries](https://developers.google.com/api-client-library).
message Status {
// The HTTP status code that corresponds to `google.rpc.Status.code`.
int32 code = 1;
// This corresponds to `google.rpc.Status.message`.
string message = 2;
// Deprecated. This field is only used by error format v1.
repeated ErrorProto errors = 3;
// This is the enum version for `google.rpc.Status.code`.
google.rpc.Code status = 4;
// This corresponds to `google.rpc.Status.details`.
repeated google.protobuf.Any details = 5;
}
// The actual error payload. The nested message structure is for backward
// compatibility with [Google API Client
// Libraries](https://developers.google.com/api-client-library). It also
// makes the error more readable to developers.
Status error = 1;
}
Exemple (lien) :
{
"error": {
"code": 400,
"message": "API key not valid. Please pass a valid API key.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "API_KEY_INVALID",
"domain": "googleapis.com",
"metadata": {
"service": "translate.googleapis.com"
}
}
]
}
}
Mappage gRPC
Différents protocoles RPC mettent en correspondance le modèle d'erreur différemment. Pour gRPC, le modèle d'erreur est compatible de façon native par le code généré et la bibliothèque d'exécution dans chaque langage disponible. Pour en savoir plus, consultez la documentation de l'API de gRPC. Par exemple, consultez le statut Java io.grpc.Status
de gRPC.
Mappage avec la bibliothèque cliente
Les bibliothèques clientes de Google peuvent choisir de relever les erreurs différemment selon les langages pour les rendre conformes aux idiomes établis. Par exemple, la bibliothèque google-cloud-go renvoie une erreur qui met en œuvre la même interface que google.rpc.Status
, alors que google-cloud-java génère une exception.
Traiter les erreurs
Vous trouverez ci-dessous un tableau contenant tous les codes d'erreur gRPC définis dans google.rpc.Code
et une brève description de leur origine. Pour gérer une erreur, vous pouvez vérifier la description du code d'état renvoyé et modifier votre appel en fonction.
HTTP | gRPC | Description |
---|---|---|
200 | OK |
Aucune erreur. |
400 | INVALID_ARGUMENT |
Le client a spécifié un argument incorrect. Consultez le message d'erreur et les détails de l'erreur pour plus d'informations. |
400 | FAILED_PRECONDITION |
La requête ne peut pas être exécutée dans l'état actuel du système, par exemple la suppression d'un répertoire non vide. |
400 | OUT_OF_RANGE |
Le client a spécifié une plage non valide. |
401 | UNAUTHENTICATED |
La requête n'a pas été authentifiée en raison d'un jeton OAuth manquant, non valide ou ayant expiré. |
403 | PERMISSION_DENIED |
Le client ne dispose pas d'une autorisation suffisante. Cela peut se produire lorsque le jeton OAuth ne dispose pas des champs d'application appropriés, car le client n'a pas d'autorisation ou car l'API n'a pas été activée. |
404 | NOT_FOUND |
Une ressource spécifiée est introuvable. |
409 | ABORTED |
Un conflit de simultanéité existe, tel qu'un conflit lecture-modification-écriture. |
409 | ALREADY_EXISTS |
La ressource qu'un client a essayé de créer existe déjà. |
429 | RESOURCE_EXHAUSTED |
Le quota de ressources est dépassé ou la limite du débit est atteinte. Pour plus d'informations, le client doit rechercher les détails de l'erreur google.rpc.QuotaFailure. |
499 | CANCELLED |
La demande a été annulée par le client. |
500 | DATA_LOSS |
Perte de données irrécupérable ou corruption de données. Le client doit signaler l'erreur à l'utilisateur. |
500 | UNKNOWN |
Erreur du serveur inconnue. Généralement un bug de serveur. |
500 | INTERNAL |
Erreur interne au serveur. Généralement un bug de serveur. |
501 | NOT_IMPLEMENTED |
Méthode d'API non mise en œuvre par le serveur. |
502 | Non disponible | Une erreur réseau s'est produite avant d'atteindre le serveur. Généralement une panne de réseau ou une mauvaise configuration. |
503 | UNAVAILABLE |
Service indisponible. Généralement, le serveur est inactif. |
504 | DEADLINE_EXCEEDED |
Délai de requête dépassé. Cela se produira uniquement si l'appelant définit un délai plus court que le délai par défaut de la méthode (le délai demandé ne suffit pas pour que le serveur traite la demande) et si la requête ne s'est pas terminée dans le délai. |
Effectuer de nouvelles tentatives à la suite d'erreurs
Les clients peuvent effectuer de nouvelles tentatives à la suite d'erreurs de type "503 UNAVAILABLE" avec un intervalle exponentiel entre les tentatives. Le délai minimum doit être égal à 1 s sauf indication contraire. La répétition par défaut des tentatives doit être fixée à une fois, sauf indication contraire.
Pour les erreurs de type "429 RESOURCE_EXHAUSTED", le client peut effectuer de nouvelles tentatives au niveau supérieur avec un délai minimal de 30 s. Ces tentatives ne sont utiles que pour les tâches en arrière-plan de longue durée.
Pour toutes les autres erreurs, il se peut que la nouvelle tentative ne s'applique pas. Assurez-vous d'abord que votre requête est idempotente et consultez la section google.rpc.RetryInfo
pour obtenir des conseils.
Propager des erreurs
Si votre service d'API dépend d'autres services, vous ne devez pas propager aveuglément les erreurs de ces services à vos clients. Lors de la traduction des erreurs, nous suggérons de suivre les conseils suivants :
- Masquez les détails de mise en œuvre et les informations confidentielles.
- Ajustez la partie responsable de l'erreur. Par exemple, un serveur qui reçoit une erreur
INVALID_ARGUMENT
d'un autre service doit propager un élémentINTERNAL
à son propre appelant.
Reproduire des erreurs
Si vous ne parvenez pas à résoudre les erreurs via l'analyse des journaux et la surveillance, essayez de reproduire les erreurs avec un test simple et reproductible. Vous pouvez utiliser ce test pour collecter plus d'informations utiles au dépannage, que vous pouvez ensuite fournir lorsque vous contactez l'assistance technique.
Nous vous recommandons d'utiliser curl -v
et les paramètres système pour reproduire les erreurs avec les API Google. Ensemble, ils peuvent reproduire presque toutes les requêtes d'API Google et vous fournir des informations de débogage détaillées. Pour plus d'informations, consultez les pages de documentation respectives de l'API que vous appelez.
Générer des erreurs
Si vous êtes un développeur de serveur, vous devez générer des erreurs avec suffisamment d'informations pour aider les développeurs du client à comprendre et à résoudre le problème. En même temps, vous devez être conscient de la sécurité et de la confidentialité des informations sur l'utilisateur et éviter de divulguer des informations sensibles dans le message d'erreur et les détails de l'erreur, car les erreurs sont souvent consignées et peuvent être accessibles par d'autres utilisateurs. Par exemple, un message d'erreur du type "L'adresse IP du client ne figure pas dans la liste blanche 128.0.0.0/8" expose des informations sur la stratégie côté serveur, qui peut être inaccessible pour l'utilisateur qui a accès au journaux.
Pour générer des erreurs appropriées, vous devez d'abord connaître google.rpc.Code
pour choisir le code d'erreur le mieux adapté à chaque condition d'erreur. Une application de serveur peut vérifier plusieurs conditions d'erreur en parallèle et renvoyer la première.
Le tableau suivant répertorie chaque code d'erreur et un exemple de message d'erreur correct.
HTTP | gRPC | Exemple de message d'erreur |
---|---|---|
400 | INVALID_ARGUMENT |
Le champ de requête xyz est xxx, le champ attendu doit être inclus dans la plage [yyy, zzz]. |
400 | FAILED_PRECONDITION |
La ressource xxx est un répertoire non vide et ne peut donc pas être supprimée. |
400 | OUT_OF_RANGE |
Le paramètre "âge" est en dehors de la plage [0, 125]. |
401 | UNAUTHENTICATED |
Identifiants d'authentification non valides. |
403 | PERMISSION_DENIED |
Autorisation "xxx" refusée sur la ressource "yyy". |
404 | NOT_FOUND |
Ressource 'xxx' introuvable. |
409 | ABORTED |
Impossible de verrouiller la ressource "xxx". |
409 | ALREADY_EXISTS |
La ressource "xxx" existe déjà. |
429 | RESOURCE_EXHAUSTED |
La limite du quota "xxx" est dépassée. |
499 | CANCELLED |
La demande a été annulée par le client. |
500 | DATA_LOSS |
Voir la remarque ci-dessous. |
500 | UNKNOWN |
Voir la remarque ci-dessous. |
500 | INTERNAL |
Voir la remarque ci-dessous. |
501 | NOT_IMPLEMENTED |
La méthode "xxx" n'a pas été mise en œuvre. |
503 | UNAVAILABLE |
Voir la remarque ci-dessous. |
504 | DEADLINE_EXCEEDED |
Voir la remarque ci-dessous. |
Charges utiles d'erreur
Le package google.rpc
définit un ensemble de charges utiles d'erreur standards, qui sont préférées aux charges utiles d'erreur personnalisées. Le tableau suivant répertorie chaque code d'erreur et sa charge utile d'erreur standard correspondante, le cas échéant. Nous recommandons aux applications avancées de rechercher ces charges utiles d'erreurs dans google.rpc.Status
lorsqu'elles gèrent les erreurs.
HTTP | gRPC | Informations sur l'erreur recommandées |
---|---|---|
400 | INVALID_ARGUMENT |
google.rpc.BadRequest |
400 | FAILED_PRECONDITION |
google.rpc.PreconditionFailure |
400 | OUT_OF_RANGE |
google.rpc.BadRequest |
401 | UNAUTHENTICATED |
google.rpc.ErrorInfo |
403 | PERMISSION_DENIED |
google.rpc.ErrorInfo |
404 | NOT_FOUND |
google.rpc.ResourceInfo |
409 | ABORTED |
google.rpc.ErrorInfo |
409 | ALREADY_EXISTS |
google.rpc.ResourceInfo |
429 | RESOURCE_EXHAUSTED |
google.rpc.QuotaFailure |
499 | CANCELLED |
|
500 | DATA_LOSS |
google.rpc.DebugInfo |
500 | UNKNOWN |
google.rpc.DebugInfo |
500 | INTERNAL |
google.rpc.DebugInfo |
501 | NOT_IMPLEMENTED |
|
503 | UNAVAILABLE |
google.rpc.DebugInfo |
504 | DEADLINE_EXCEEDED |
google.rpc.DebugInfo |