Erreurs

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 et qui nous permet d'offrir une expérience cohérente sur les différentes API, différents protocoles d'API (tels que gRPC ou HTTP) et des contextes d'erreur différents (tels que asynchrones,{ 101}erreur de lot 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, une instance qui 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 des meilleurs mappages idiomatiques dans les bibliothèques clientes et réduit la complexité de la logique client sans restreindre l'inclusion des 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. Pour référence, gérer en moyenne trois codes d'erreur par appel d'API signifierait que la plupart des logiques d'application concernent la gestion des erreurs, ce qui n'entraînerait 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 supposez pas que l'utilisateur est un expert de votre API. Les utilisateurs peuvent être des développeurs clients, des opérateurs, 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 structurées sur les erreurs, qui est à la fois stable et extensible.
  • RetryInfo: indique quand les clients peuvent relancer une requête ayant échoué, peut être renvoyé sur Code.UNAVAILABLE ou Code.ABORTED
  • QuotaFailure: décrit l'échec d'une vérification des quotas, peut être renvoyé le Code.RESOURCE_EXHAUSTED
  • BadRequest: décrit les cas de non-respect dans une requête client, peut être renvoyé le Code.INVALID_ARGUMENT

Informations sur l'erreur

ErrorInfo est un type particulier de charge utile d'erreur. Elle fournit des informations sur les erreurs stable et extensible sur lesquelles peuvent reposer à la fois des humains et des applications. 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 HTTP de l'utilisateur authentifié, ou le paramètre language_code dans la requête pour déterminer la langue de la localisation.

Mappage d'erreurs

Les API Google sont accessibles dans différents environnements de programmation. Chaque environnement possède généralement son propre mode de gestion des erreurs. Les sections suivantes expliquent comment le modèle d'erreur est mappé dans les environnements couramment utilisés.

Mappage HTTP

Alors que les messages proto3 possèdent un encodage JSON natif, la plate-forme d'API de Google utilise un schéma d'erreur différent pour les API HTTP JSON de Google à des fins 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 (link):

{
  "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 si le jeton OAuth ne dispose pas des champs d'application appropriés, si le client ne dispose pas des autorisations requises, ou si 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 de parvenir au serveur. Il s'agit généralement d'une panne ou d'une mauvaise configuration réseau.
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.

Relancer les 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 de tentatives par défaut doit être effectué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.

Erreurs de propagation

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ément INTERNAL à son propre appelant.

Reproduire des erreurs

Si vous ne parvenez pas à résoudre les erreurs via l'analyse des journaux et la surveillance, vous devez essayer de reproduire les erreurs à l'aide d'un test simple et reproductible. Vous pouvez utiliser ce test pour recueillir plus d'informations de dépannage que vous pouvez fournir lorsque vous contactez l'assistance technique.

Nous vous recommandons d'utiliser oauth2l, curl -v et Paramètres système pour reproduire les erreurs API Google. Ensemble, ils peuvent reproduire presque toutes les requêtes des API Google et vous fournir des informations de débogage détaillées. Pour en savoir plus, consultez les pages de documentation 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 sur la liste d'autorisation 128.0.0.0/8" présente des informations sur la stratégie côté serveur, qui ne sont peut-être pas accessibles à l'utilisateur ayant accès. dans les 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'erreur dans google.rpc.Status lorsqu'elles gèrent des 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