Fehlerantworten

Standardfehlerantworten

Wenn eine Reporting API-Anfrage erfolgreich ist, gibt die API 200 zurück. Wenn bei einer Anfrage ein Fehler auftritt, gibt die API in der Antwort einen HTTP-Statuscode, Status und Grund basierend auf dem Fehlertyp zurück. Darüber hinaus enthält der Antworttext eine detaillierte Beschreibung der Fehlerursache. Hier ist ein Beispiel für eine Fehlerantwort:

{
 "error": {
  "code": 403,
  "message": "User does not have sufficient permissions for this profile.",
  "status": "PERMISSION_DENIED"
 }
}

Fehlertabelle

Code Status Beschreibung Empfohlene Maßnahme
400 INVALID_ARGUMENT Die Anforderung ist ungültig. Möglicherweise fehlt ein erforderliches Argument, überschreitet die Grenzwerte oder hat einen ungültigen Wert. Weitere Informationen finden Sie in der Fehlermeldung. Dieser Fehler tritt wieder auf, wenn der Client ihn wiederholt.
401 UNAUTHENTICATED Der Client ist nicht ordnungsgemäß authentifiziert. Wiederholen Sie den Vorgang nur, wenn das Problem behoben ist. Sie müssen ein neues Authentifizierungstoken anfordern.
403 PERMISSION_DENIED Gibt die Datenanfrage an, auf die der Nutzer keinen Zugriff hat. Wiederholen Sie den Vorgang nur, wenn das Problem behoben ist. Sie benötigen ausreichende Berechtigungen, um den Vorgang für die angegebene Entität auszuführen.
429 RESOURCE_EXHAUSTED AnalyticsDefaultGroupCLIENT_PROJECT-1d Gibt an, dass das Kontingent für Anfragen pro Tag und Projekt erschöpft ist. Wiederholen Sie den Vorgang nur, wenn das Problem behoben ist. Sie haben Ihr Tageskontingent aufgebraucht.
429 RESOURCE_EXHAUSTED AnalyticsDefaultGroupCLIENT_PROJECT-100s Gibt an, dass das Kontingent für Anfragen pro 100 Sekunden und Projekt aufgebraucht ist. Wiederholen Sie den Vorgang mit dem exponentiellen Backoff. Sie müssen die Geschwindigkeit, mit der Sie die Anfragen senden, verringern.
429 RESOURCE_EXHAUSTED AnalyticsDefaultGroupUSER-100s Gibt an, dass das Kontingent Anfragen pro 100 Sekunden pro Nutzer und Projekt aufgebraucht ist. Wiederholen Sie den Vorgang mit dem exponentiellen Backoff. Sie müssen die Geschwindigkeit, mit der Sie die Anfragen senden, verringern.
429 RESOURCE_EXHAUSTED DiscoveryGroupCLIENT_PROJECT-100s Zeigt an, dass das Erkennungskontingent für Anfragen pro 100 Sekunden aufgebraucht ist. Die Antwort für die Erkennung ändert sich nicht häufig. Speichern Sie die Antwort entweder lokal im Cache oder versuchen Sie es noch einmal mit dem exponentiellen Backoff. Sie müssen die Rate verlangsamen, mit der Sie die Anfragen senden.
500 INTERNAL Ein unerwarteter interner Serverfehler ist aufgetreten. Wiederholen Sie diese Abfrage nur einmal.
503 BACKEND_ERROR Der Server hat einen Fehler zurückgegeben. Wiederholen Sie diese Abfrage nur einmal.
503 UNAVAILABLE Der Dienst konnte die Anfrage nicht verarbeiten. Dies ist höchstwahrscheinlich ein vorübergehender Zustand und kann durch einen erneuten Versuch mit exponentiellem Backoff behoben werden.

Exponentiellen Backoff implementieren

Ein exponentieller Backoff ist der Prozess, bei dem ein Client eine fehlgeschlagene Anfrage regelmäßig wiederholt, während er immer länger wird. Es ist eine standardmäßige Fehlerbehandlungsstrategie für Netzwerkanwendungen. Bei der Entwicklung der Reporting API wird erwartet, dass Clients, die fehlgeschlagene Anfragen wiederholen, dies mithilfe eines exponentiellen Backoffs tun. Der exponentielle Backoff ist nicht nur „erforderlich“, sondern erhöht auch die Effizienz der Bandbreitennutzung, die Anzahl der für eine erfolgreiche Antwort erforderlichen Anfragen und maximiert den Durchsatz von Anfragen in Umgebungen, die gleichzeitig ausgeführt werden.

Der Ablauf zur Implementierung eines einfachen exponentiellen Backoffs sieht so aus:

  1. Anfrage an die API stellen
  2. Sie erhalten eine Fehlerantwort mit einem wiederholbaren Fehlercode
  3. 1 Sek. + random_number_milliseconds Sekunden warten
  4. Anfrage wiederholen
  5. Sie erhalten eine Fehlerantwort mit einem wiederholbaren Fehlercode
  6. 2 Sek. + random_number_milliseconds Sekunden warten
  7. Anfrage wiederholen
  8. Sie erhalten eine Fehlerantwort mit einem wiederholbaren Fehlercode
  9. 4 Sek. + random_number_milliseconds Sekunden warten
  10. Anfrage wiederholen
  11. Sie erhalten eine Fehlerantwort mit einem wiederholbaren Fehlercode
  12. 8 Sek. + random_number_milliseconds Sekunden warten
  13. Anfrage wiederholen
  14. Sie erhalten eine Fehlerantwort mit einem wiederholbaren Fehlercode
  15. 16 Sek. + random_number_milliseconds Sekunden warten
  16. Anfrage wiederholen
  17. Wenn Sie weiterhin einen Fehler erhalten, beenden Sie den Vorgang und protokollieren Sie ihn.

Im obigen Ablauf ist random_number_milliseconds eine zufällige Anzahl von Millisekunden, die kleiner oder gleich 1.000 ist. Dies ist erforderlich, um bestimmte Sperrfehler in einigen gleichzeitigen Implementierungen zu vermeiden. random_number_milliseconds muss nach jeder Wartezeit neu definiert werden.

Hinweis: Die Wartezeit beträgt immer (2 ^ n) + random_number_milliseconds, wobei n eine monoton ansteigende Ganzzahl ist, die anfänglich als 0 definiert ist. n wird bei jeder Iteration (jede Anfrage) um 1 erhöht.

Der Algorithmus ist so eingerichtet, dass er endet, wenn n = 5. Diese Obergrenze verhindert nur, dass Clients unbegrenzte Wiederholungen ausführen. Sie führt zu einer Gesamtverzögerung von etwa 32 Sekunden, bevor eine Anfrage als "nicht behebbarer Fehler" gilt.

Der folgende Python-Code ist eine Implementierung des obigen Ablaufs zum Beheben von Fehlern, die in einer Methode namens makeRequest auftreten.

import random
import time
from apiclient.errors import HttpError

def makeRequestWithExponentialBackoff(analytics):
  """Wrapper to request Google Analytics data with exponential backoff.

  The makeRequest method accepts the analytics service object, makes API
  requests and returns the response. If any error occurs, the makeRequest
  method is retried using exponential backoff.

  Args:
    analytics: The analytics service object

  Returns:
    The API response from the makeRequest method.
  """
  for n in range(0, 5):
    try:
      return makeRequest(analytics)

    except HttpError, error:
      if error.resp.reason in ['userRateLimitExceeded', 'quotaExceeded',
                               'internalServerError', 'backendError']:
        time.sleep((2 ** n) + random.random())
      else:
        break

  print "There has been an error, the request never succeeded."