Fehler

Dieses Kapitel gibt einen Überblick über das Fehlermodell für Google APIs. Es bietet auch eine allgemeine Anleitung dazu, wie Entwickler Fehler ordnungsgemäß generieren und beheben können.

Google APIs verwenden ein einfaches protokollunabhängiges Fehlermodell, das es uns ermöglicht, eine konsistente Erfahrung für verschiedene APIs, verschiedene API-Protokolle (z. B. gRPC oder HTTP) und verschiedene Fehlerkontexte (z. B. asynchrone, Batch- oder Workflowfehler) zu bieten.

Fehlermodell

Das Fehlermodell für Google APIs wird logisch durch google.rpc.Status definiert. Diese Instanz wird bei einem API-Fehler an den Client zurückgegeben. Das folgende Code-Snippet zeigt den allgemeinen Aufbau des Fehlermodells:

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;
}

Da die meisten Google APIs ein ressourcenorientiertes API-Design verwenden, erfolgt auch die Fehlerbehebung nach diesem Designprinzip. Dabei wird ein kleiner Satz von Standardfehlern für eine große Anzahl von Ressourcen genutzt. Anstatt beispielsweise verschiedene Arten von "nicht gefundenen" Fehlern zu definieren, verwendet der Server einen Standardfehlercode google.rpc.Code.NOT_FOUND und teilt dem Client mit, welche Ressource nicht gefunden wurde. Der verhältnismäßig kleine Fehlerbereich vereinfacht die Dokumentation und die Clientlogik. Außerdem sind bessere idiomatische Zuordnungen in Clientbibliotheken möglich und umsetzbare Informationen lassen sich uneingeschränkt einbeziehen.

Fehlercodes

Google APIs müssen die von google.rpc.Code definierten kanonischen Fehlercodes verwenden. In den einzelnen APIs dürfen keine zusätzlichen Fehlercodes definiert werden, da Entwickler in der Regel keine Logiken zur Verarbeitung einer großen Anzahl von Fehlercodes schreiben. Eine Verarbeitung von durchschnittlich drei Fehlercodes pro API-Aufruf bedeutet beispielsweise, dass die meisten Anwendungslogik nur für die Fehlerbehandlung vorgesehen ist, was für Entwickler keine gute Lösung wäre.

Fehlermeldungen

Fehlermeldungen sollen Nutzern helfen, API-Fehler schnell und einfach zu verstehen und zu beheben. Beachten Sie beim Schreiben von Fehlermeldungen generell die folgenden Richtlinien:

  • Gehen Sie nicht davon aus, dass der Nutzer ein erfahrener Nutzer Ihrer API ist. Nutzer können Cliententwickler, Betriebspersonal, IT-Mitarbeiter oder Endnutzer von Anwendungen sein.
  • Gehen Sie nicht davon aus, dass Nutzer etwas über Ihre Dienstimplementierung wissen oder mit Fehlerkontexten wie etwa Log-Analysen vertraut sind.
  • Fehlermeldungen sollten nach Möglichkeit so konstruiert sein, dass auch technische Nutzer, die keine Entwickler Ihrer API sind, auf den Fehler reagieren und ihn beheben können.
  • Halten Sie Fehlermeldungen kurz. Geben Sie bei Bedarf einen Link an, über den Nutzer Fragen stellen, Feedback geben oder weitere Informationen erhalten können, die den Rahmen der Fehlermeldung an sich sprengen würden. Verwenden Sie andernfalls das erweiterbare Detailfeld.

Fehlerdetails

Google APIs definieren eine Reihe standardmäßiger Fehlernutzlasten für Fehlerdetails. Sie finden diese unter google/rpc/error_details.proto. Fehlerdetails decken die gängigsten Anforderungen für API-Fehler wie Kontingentfehler und ungültige Parameter ab. Wie Fehlercodes sollten Entwickler diese Standardnutzlasten nach Möglichkeit verwenden.

Zusätzliche Fehlerdetailtypen sollten nur eingeführt werden, wenn sie ergänzend zum Anwendungscode zur Fehlerbehebung beitragen. Wenn die Fehlerinformationen nur von Nutzern verarbeitet werden, geben Sie den Fehlermeldungsinhalt an und lassen Sie Entwickler den Fehler manuell beheben, anstatt zusätzliche Fehlerdetailtypen einzuführen.

Hier einige Beispiele für error_details-Nutzlasten:

  • ErrorInfo stellt strukturierte Fehlerinformationen bereit, die sowohl stabil als auch erweiterbar sind.
  • RetryInfo beschreibt, wann Clients eine fehlgeschlagene Anfrage wiederholen können. Die Rückgabe erfolgt gegebenenfalls bei Code.UNAVAILABLE oder Code.ABORTED.
  • QuotaFailure beschreibt, wie eine Kontingentprüfung fehlgeschlagen ist. Die Rückgabe erfolgt gegebenenfalls bei Code.RESOURCE_EXHAUSTED.
  • BadRequest beschreibt Verstöße in einer Clientanfrage. Die Rückgabe erfolgt gegebenenfalls bei Code.INVALID_ARGUMENT.

Fehlerinformation

ErrorInfo ist eine spezielle Art von Fehlernutzlast. Sie bietet stabile und erweiterbare Fehlerinformationen, auf die sowohl Nutzer als auch Anwendungen angewiesen sind. Jede ErrorInfo hat drei Informationen: eine Fehlerdomain, einen Fehlergrund und eine Reihe von Fehlermetadaten, wie in diesem Beispiel. Weitere Informationen finden Sie in der Definition von ErrorInfo.

Bei Google APIs ist die primäre Fehlerdomain googleapis.com und die entsprechenden Fehlerursachen werden durch die Aufzählung google.api.ErrorReason definiert. Weitere Informationen finden Sie in der Definition der google.api.ErrorReason.

Fehlerlokalisierung

Das Feld message in google.rpc.Status ist für Entwickler bestimmt und muss auf Englisch sein.

Wenn Sie eine Fehlermeldung für Nutzer benötigen, verwenden Sie google.rpc.LocalizedMessage als Detailfeld. Das Nachrichtenfeld in google.rpc.LocalizedMessage kann lokalisiert werden. Achten Sie darauf, dass das Nachrichtenfeld in google.rpc.Status auf Englisch ist.

Standardmäßig sollte der API-Dienst das Gebietsschema des authentifizierten Nutzers oder den HTTP Accept-Language-Header oder den Parameter language_code in der Anfrage verwenden, um die Sprache für die Lokalisierung zu bestimmen.

Fehlerzuordnung

Google APIs sind in verschiedenen Programmierumgebungen zugänglich. Jede Umgebung hat in der Regel eine eigene Methode zur Fehlerbehandlung. In den folgenden Abschnitten wird erläutert, wie das Fehlermodell in häufig verwendeten Umgebungen zugeordnet wird.

HTTP-Zuordnung

Proto3-Nachrichten haben eine native JSON-Codierung. Die Google API Platform verwendet hingegen aus Gründen der Abwärtskompatibilität ein anderes Fehlerschema für die HTTP-APIs von Google.

Schema:

// 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;
}

Beispiel (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"
        }
      }
    ]
  }
}

gRPC-Zuordnung

Das Fehlermodell wird von unterschiedlichen RPC-Protokollen auf unterschiedliche Weise zugeordnet. gRPC wird das Fehlermodell nativ durch den generierten Code und die Laufzeitbibliothek in den verfügbaren Sprachen unterstützt. Weitere Informationen finden Sie in der API-Dokumentation für gRPC. Sehen Sie sich beispielsweise das io.grpc.Status von gRPC Java an.

Clientbibliothek-Zuordnung

Google-Clientbibliotheken können Fehler je nach Sprache unterschiedlich wiedergeben, um den gängigen Dialekten gerecht zu werden. Beispielsweise gibt die Bibliothek google-cloud-go einen Fehler zurück, der dieselbe Schnittstelle wie google.rpc.Status implementiert, während google-cloud-java eine Ausnahme auslöst.

Fehlerbehebung

In der nachfolgenden Tabelle sind alle gRPC-Fehlercodes aufgeführt, die in google.rpc.Code definiert sind, und eine kurze Beschreibung ihrer Ursache. Zur Fehlerbehebung können Sie die Beschreibung des zurückgegebenen Statuscodes prüfen und den Aufruf entsprechend ändern.

HTTP gRPC Beschreibung
200 OK Kein Fehler
400 INVALID_ARGUMENT Der Client hat ein ungültiges Argument angegeben. Weitere Informationen finden Sie in der Fehlermeldung und den Fehlerdetails.
400 FAILED_PRECONDITION Die Anfrage, wie etwa das Löschen eines Verzeichnisses mit Inhalt, kann im aktuellen Systemzustand nicht ausgeführt werden.
400 OUT_OF_RANGE Der Client hat einen ungültigen Bereich angegeben.
401 UNAUTHENTICATED Die Anfrage konnte aufgrund eines fehlenden, ungültigen oder abgelaufenen OAuth-Tokens nicht authentifiziert werden.
403 PERMISSION_DENIED Der Client verfügt nicht über die erforderliche Berechtigung. Dies kann vorkommen, wenn das OAuth-Token nicht über die richtigen Bereiche verfügt, der Client keine Berechtigung besitzt oder die API nicht aktiviert wurde.
404 NOT_FOUND Eine angegebene Ressource wurde nicht gefunden.
409 ABORTED Gibt einen Konflikt aufgrund von gleichzeitig ausgeführten Aktionen an, wie etwa einen Read-Modify-Write-Konflikt.
409 ALREADY_EXISTS Die von einem Client zu erstellende Ressource ist bereits vorhanden.
429 RESOURCE_EXHAUSTED Entweder wurde das Ressourcenkontingent überschritten oder das Ratenlimit erreicht. Der Client sollte in den Fehlerdetails zu google.rpc.QuotaFailure nach weiteren Informationen suchen.
499 CANCELLED Request cancelled by the client.
500 DATA_LOSS Dauerhafter Datenverlust oder Datenkorruption. Der Client sollte den Fehler dem Nutzer melden.
500 UNKNOWN Unbekannter Serverfehler. In der Regel ein Serverprogrammfehler.
500 INTERNAL Interner Serverfehler. In der Regel ein Serverprogrammfehler.
501 NOT_IMPLEMENTED Die API-Methode wurde vom Server nicht implementiert.
502 Ein Netzwerkfehler ist aufgetreten, bevor der Server erreicht wurde. In der Regel ein Netzwerkausfall oder eine fehlerhafte Konfiguration.
503 UNAVAILABLE Dienst nicht verfügbar. In der Regel ist der Server ausgefallen.
504 DEADLINE_EXCEEDED Die Frist der Anfrage wurde überschritten. Dies geschieht nur, wenn für den Aufruf eine Frist festgelegt wurde, die kürzer ist als die Standardfrist der Methode (d. h., die angeforderte Frist reicht nicht aus, damit der Server die Anfrage bearbeitet), und die Anfrage nicht innerhalb der Frist abgeschlossen wurde.

Nach Fehler wiederholen

Clients können bei 503 NICHT VERFÜGBAREN Fehlern mit exponentiellem Backoff den Vorgang wiederholen. Die Mindestverzögerung sollte 1 Sekunde betragen, sofern nicht anders angegeben. Die Standardwiederholung sollte einmalig sein, sofern nicht anders angegeben.

Bei 429 RESOURCE_EXHAUSTED-Fehlern kann der Client den Versuch mit einer Verzögerung von mindestens 30 Sekunden auf der höheren Ebene wiederholen. Solche Wiederholungsversuche sind nur für lang andauernde Hintergrundjobs nützlich.

Bei allen anderen Fehlern ist keine Wiederholung möglich. Stellen Sie zuerst sicher, dass Ihre Anfrage idempotent ist, und lesen Sie die Anleitung unter google.rpc.RetryInfo.

Fehler weitergeben

Wenn der API-Dienst von anderen Diensten abhängt, sollten Sie Fehler von diesen Diensten nicht ungesehen an Ihre Clients weitergeben. Wir empfehlen beim Übersetzen von Fehlern Folgendes:

  • Blenden Sie Details zur Implementierung sowie vertrauliche Informationen aus.
  • Passen Sie die für den Fehler zuständige Partei an. Beispielsweise sollte ein Server, der von einem anderen Dienst den Fehler INVALID_ARGUMENT empfängt, an seinen eigenen Aufrufer den Fehler INTERNAL weiterleiten.

Fehler reproduzieren

Wenn Sie Fehler nicht durch die Analyse von Logs und Monitoring beheben können, sollten Sie versuchen, die Fehler mit einem einfachen und wiederholbaren Test zu reproduzieren. Mit dem Test können Sie weitere Informationen zur Fehlerbehebung erfassen, die Sie dem technischen Support zur Verfügung stellen können.

Wir empfehlen die Verwendung von curl -v und Systemparametern, um Fehler mit Google APIs zu reproduzieren. Sie können fast alle Google API-Anfragen reproduzieren und ausführliche Informationen zur Fehlerbehebung liefern. Weitere Informationen finden Sie auf den entsprechenden Dokumentationsseiten der aufgerufenen API.

Fehler generieren

Wenn Sie Serverentwickler sind, sollten Sie Fehler mit ausreichenden Informationen generieren, damit Cliententwickler das Problem verstehen und beheben können. Gleichzeitig müssen Sie die Sicherheit und Vertraulichkeit der Nutzerdaten berücksichtigen und die Offenlegung vertraulicher Informationen in der Fehlermeldung und den Fehlerdetails vermeiden. Der Grund dafür ist, dass Fehler häufig protokolliert werden und gegebenenfalls für andere Nutzer zugänglich sind. Eine Fehlermeldung wie "Client IP address is not on whitelist 128.0.0.0/8" legt beispielsweise Informationen über die serverseitige Richtlinie offen, auf die der Nutzer mit Zugriff auf die Logs normalerweise keinen Zugriff hat.

Um korrekte Fehler zu generieren, müssen Sie zuerst mit google.rpc.Code vertraut sein, um den am besten geeigneten Fehlercode für jede Fehlerbedingung auszuwählen. Eine Serveranwendung kann mehrere Fehlerbedingungen parallel prüfen und die erste zurückgeben.

In der folgenden Tabelle sind die Fehlercodes mit je einem Beispiel einer guten Fehlermeldung aufgeführt.

HTTP gRPC Beispiel für Fehlermeldung
400 INVALID_ARGUMENT Request field x.y.z is xxx, expected one of [yyy, zzz].
400 FAILED_PRECONDITION Resource xxx is a non-empty directory, so it cannot be deleted.
400 OUT_OF_RANGE Parameter 'age' is out of range [0, 125].
401 UNAUTHENTICATED Invalid authentication credentials.
403 PERMISSION_DENIED Permission 'xxx' denied on resource 'yyy'.
404 NOT_FOUND Resource 'xxx' not found.
409 ABORTED Couldn’t acquire lock on resource ‘xxx’.
409 ALREADY_EXISTS Resource 'xxx' already exists.
429 RESOURCE_EXHAUSTED Quota limit 'xxx' exceeded.
499 CANCELLED Request cancelled by the client.
500 DATA_LOSS See note.
500 UNKNOWN See note.
500 INTERNAL See note.
501 NOT_IMPLEMENTED Method 'xxx' not implemented.
503 UNAVAILABLE See note.
504 DEADLINE_EXCEEDED Siehe Hinweis.

Fehlernutzlasten

Das Paket google.rpc definiert eine Reihe von Standardfehlernutzlasten, die benutzerdefinierten Fehlernutzlasten vorgezogen werden. In der folgenden Tabelle sind die Fehlercodes und deren standardmäßige Fehlernutzlast aufgelistet, falls zutreffend. Bei der Behebung von Fehlern in erweiterten Anwendungen sollte nach diesen Fehlernutzlasten in google.rpc.Status gesucht werden.

HTTP gRPC Empfohlenes Fehlerdetail
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