Odpowiedzi na błędy

Standardowe odpowiedzi na błędy

Jeśli żądanie do interfejsu Core Reporting API zostanie zrealizowane, zwróci on kod stanu 200. Jeśli w żądaniu wystąpi błąd, interfejs API zwróci kod stanu HTTP, stan i przyczynę w odpowiedzi zależnie od typu błędu. Dodatkowo treść odpowiedzi zawiera szczegółowy opis przyczyny błędu. Przykładowa odpowiedź na błąd:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "invalidParameter",
    "message": "Invalid value '-1' for max-results. Value must be within the range: [1, 1000]",
    "locationType": "parameter",
    "location": "max-results"
   }
  ],
  "code": 400,
  "message": "Invalid value '-1' for max-results. Value must be within the range: [1, 1000]"
 }
}

Tabela błędów

Kod Przyczyna Opis Zalecane działanie
400 invalidParameter Wskazuje, że parametr żądania ma nieprawidłową wartość. Pola locationType i location w odpowiedzi na błąd zawierają informacje o tym, która wartość była nieprawidłowa. Nie ponawiaj próby bez rozwiązania problemu. Musisz podać prawidłową wartość parametru wskazanego w odpowiedzi na błąd.
400 badRequest Wskazuje, że zapytanie jest nieprawidłowe. Może to być np. brak identyfikatora nadrzędnego lub żądana kombinacja wymiarów bądź danych była nieprawidłowa. Nie ponawiaj próby bez rozwiązania problemu. Aby zapytanie do interfejsu API działało, musisz wprowadzić w nim zmiany.
401 invalidCredentials Wskazuje, że token uwierzytelniania jest nieprawidłowy lub stracił ważność. Nie ponawiaj próby bez rozwiązania problemu. Musisz uzyskać nowy token uwierzytelniania.
403 insufficientPermissions Wskazuje, że użytkownik nie ma wystarczających uprawnień do elementu określonego w zapytaniu. Nie ponawiaj próby bez rozwiązania problemu. Musisz mieć wystarczające uprawnienia do wykonania tej operacji na określonej encji.
403 dailyLimitExceeded Wskazuje, że użytkownik przekroczył dzienny limit (na projekt lub na widok (profil)). Nie ponawiaj próby bez rozwiązania problemu. Dzienny limit został wykorzystany. Zobacz Limity i limity interfejsu API.
403 userRateLimitExceeded Wskazuje, że został przekroczony limit zapytań na 100 sekund na użytkownika. Domyślna wartość ustawiona w Konsoli interfejsów API Google to 100 zapytań na 100 sekund na użytkownika. W Konsoli interfejsów API Google możesz zwiększyć ten limit do maksymalnie 1000. Spróbuj ponownie, stosując wykładniczy czas do ponowienia. Musisz zmniejszyć częstotliwość wysyłania żądań.
403 rateLimitExceeded Wskazuje, że zostały przekroczone limity liczby zapytań na 100 sekund projektu. Spróbuj ponownie, stosując wykładniczy czas do ponowienia. Musisz zmniejszyć częstotliwość wysyłania żądań.
403 quotaExceeded Wskazuje, że osiągnięto 10 równoczesnych żądań na widok (profil) w interfejsie API podstawowego raportowania. Spróbuj ponownie, stosując wykładniczy czas do ponowienia. Poczekaj na zakończenie co najmniej jednego trwającego żądania dla tego widoku (profilu).
500 internalServerError Wystąpił nieoczekiwany wewnętrzny błąd serwera. Nie ponawiaj tego zapytania więcej niż raz.
503 backendError Serwer zwrócił błąd. Nie ponawiaj tego zapytania więcej niż raz.

Obsługa odpowiedzi 500 lub 503

Podczas dużego obciążenia lub bardziej złożonych żądań może wystąpić błąd 500 lub 503. W przypadku większych żądań rozważ wysłanie prośby o dane dla krótszego okresu. Rozważ też wdrożenie wykładniczego czasu do ponowienia. Częstotliwość tych błędów może zależeć od widoku (profilu) i ilości danych raportowania powiązanych z tym widokiem. Zapytanie, które powoduje błąd 500 lub 503 w jednym widoku danych (profilu), nie musi powodować błędu dla tego samego zapytania w innym widoku danych (profilu).

Wdrażanie wykładniczego ponowienia

Wykładniczy czas do ponowienia to proces, w którym klient okresowo ponawia próby nieudanego żądania w coraz większym czasie. To standardowa strategia obsługi błędów w aplikacjach sieciowych. Interfejs Core Reporting API został zaprojektowany z założeniem, że klienci, którzy zdecydują się ponawiać nieudane żądania, będą to robić ze wzrastającym czasem do ponowienia. Oprócz tego, że jest to „wymagane”, zastosowanie wykładniczego ponowienia zwiększa wydajność wykorzystania przepustowości, zmniejsza liczbę żądań wymaganych do uzyskania pomyślnej odpowiedzi i maksymalizuje przepustowość żądań w środowiskach równoczesnych.

Proces implementacji prostego wzrastającego czasu do ponowienia jest następujący.

  1. Wysyłanie żądania do interfejsu API
  2. Otrzymuj odpowiedź o błędzie zawierającą kod błędu z możliwością ponowienia próby
  3. Zaczekaj 1 s + random_number_milliseconds s
  4. Ponów prośbę
  5. Otrzymuj odpowiedź o błędzie zawierającą kod błędu z możliwością ponowienia próby
  6. Zaczekaj 2 s + random_number_milliseconds s
  7. Ponów prośbę
  8. Otrzymuj odpowiedź o błędzie zawierającą kod błędu z możliwością ponowienia próby
  9. Czekaj 4 + random_number_milliseconds s
  10. Ponów prośbę
  11. Otrzymuj odpowiedź o błędzie zawierającą kod błędu z możliwością ponowienia próby
  12. Odczekaj 8 s + random_number_milliseconds s
  13. Ponów prośbę
  14. Otrzymuj odpowiedź o błędzie zawierającą kod błędu z możliwością ponowienia próby
  15. Zaczekaj 16 s + random_number_milliseconds s
  16. Ponów prośbę
  17. Jeśli błąd nadal występuje, zatrzymaj go i zapisz go.

W tym przypadku random_number_milliseconds jest losową liczbą milisekund równą 1000 lub mniejszą. Jest to konieczne, aby uniknąć pewnych błędów blokady w niektórych równoczesnych implementacjach. Po każdym oczekiwaniu należy ponownie zdefiniować pole random_number_milliseconds.

Uwaga: czas oczekiwania to zawsze (2 ^ n) + random_number_milliseconds, gdzie n to monotonicznie rosnąca liczba całkowita zdefiniowana początkowo jako 0. Wartość n zwiększa się o 1 w każdej iteracji (każde żądanie).

Algorytm kończy działanie, gdy n = 5. Ten limit ma na celu powstrzymanie klientów przed nieskończonym ponawianiem prób, przez co całkowite opóźnienie wynosi około 32 sekundy, zanim żądanie zostanie uznane za „błąd nieodwracalny”.

Poniższy kod Pythona jest implementacją powyższego procesu przywracania po wystąpieniu błędów występujących w metodzie makeRequest.

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."