Odpowiedzi na błędy

Standardowe odpowiedzi na błędy

Jeśli żądanie do interfejsu Reporting API zostanie zrealizowane, zwróci on wartość 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": {
  "code": 403,
  "message": "User does not have sufficient permissions for this profile.",
  "status": "PERMISSION_DENIED"
 }
}

Tabela błędów

Kod Stan Opis Zalecane działanie
400 INVALID_ARGUMENT Żądanie jest nieprawidłowe. Może brakować wymaganego argumentu, przekracza on limity lub ma nieprawidłową wartość. Więcej informacji znajdziesz w komunikacie o błędzie. Ten błąd wystąpi ponownie, jeśli klient spróbuje ponownie.
401 UNAUTHENTICATED Klient nie jest poprawnie uwierzytelniony. Nie ponawiaj próby bez rozwiązania problemu. Musisz uzyskać nowy token uwierzytelniania.
403 PERMISSION_DENIED Wskazuje żądanie udostępnienia danych, do których użytkownik nie ma dostępu. Nie ponawiaj próby bez rozwiązania problemu. Musisz mieć wystarczające uprawnienia do wykonania tej operacji na określonej encji.
429 RESOURCE_EXHAUSTED AnalyticsDefaultGroupCLIENT_PROJECT-1d Wskazuje, że limit żądań dziennie na projekt został wyczerpany. Nie ponawiaj próby bez rozwiązania problemu. Dzienny limit został wykorzystany.
429 RESOURCE_EXHAUSTED AnalyticsDefaultGroupCLIENT_PROJECT-100s Wskazuje, że limit żądań na 100 sekund na projekt został wyczerpany. Spróbuj ponownie, stosując wykładniczy czas do ponowienia. Musisz zmniejszyć częstotliwość wysyłania żądań.
429 RESOURCE_EXHAUSTED AnalyticsDefaultGroupUSER-100s Wskazuje, że limit żądań na 100 sekund na użytkownika na projekt został wyczerpany. Spróbuj ponownie, stosując wykładniczy czas do ponowienia. Musisz zmniejszyć częstotliwość wysyłania żądań.
429 RESOURCE_EXHAUSTED DiscoveryGroupCLIENT_PROJECT-100s Wskazuje, że limit żądań wykrywania na 100 sekund został wyczerpany. Odpowiedź wykrywania nie zmienia się często. Zapisz ją w pamięci podręcznej lokalnie lub spróbuj ponownie, używając wykładniczego ponawiania. Musisz zmniejszyć częstotliwość wysyłania żądań.
500 INTERNAL Wystąpił nieoczekiwany wewnętrzny błąd serwera. Nie ponawiaj tego zapytania więcej niż raz.
503 BACKEND_ERROR Serwer zwrócił błąd. Nie ponawiaj tego zapytania więcej niż raz.
503 UNAVAILABLE Usługa nie mogła przetworzyć żądania. Jest to najprawdopodobniej stan przejściowy, który można rozwiązać, ponawiając próbę z wykładniczym opóźnieniem.

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