Odpowiedzi na błędy

Standardowe odpowiedzi na błędy

Jeśli żądanie do interfejsu API do raportowania zostanie zrealizowane, interfejs API zwróci wartość 200. Jeśli w żądaniu wystąpi błąd, interfejs API zwraca w odpowiedzi kod stanu HTTP, stan i przyczynę odpowiednio do typu błędu. Poza tym treść odpowiedzi zawiera szczegółowy opis przyczyny błędu. Oto przykładowa odpowiedź o błędzie:

{
 "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żliwe, że brakuje wymaganego argumentu, przekracza on limity lub ma nieprawidłową wartość. Aby dowiedzieć się więcej, przeczytaj komunikat o błędzie. Ten błąd wystąpi ponownie, jeśli klient spróbuje ponownie.
401 UNAUTHENTICATED Klient nie jest prawidłowo uwierzytelniony. Nie ponawiaj próby bez rozwiązania problemu. Musisz uzyskać nowy token uwierzytelniania.
403 PERMISSION_DENIED Wskazuje żądanie dostępu do danych, do których użytkownik nie ma dostępu. Nie ponawiaj próby bez rozwiązania problemu. Aby wykonać operację na określonym elemencie, musisz mieć wystarczające uprawnienia.
429 RESOURCE_EXHAUSTED AnalyticsDefaultGroupCLIENT_PROJECT-1d Wskazuje, że limit dziennej liczby żądań 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, korzystając z wykładniczego ponowienia. Musisz zmniejszyć częstotliwość wysyłania żądań.
429 RESOURCE_EXHAUSTED AnalyticsDefaultGroup-100 s Informuje, że został wyczerpany limit żądań na 100 sekund na użytkownika na projekt. Spróbuj ponownie, korzystając z wykładniczego ponowienia. Musisz zmniejszyć częstotliwość wysyłania żądań.
429 RESOURCE_EXHAUSTED DiscoveryGroup_PROJECT-100 s Wskazuje, że limit wykrywania żądań na 100 sekund został wyczerpany. Odpowiedź wykrywania rzadko się zmienia. Odpowiedź wykrywania znajduje się w pamięci podręcznej lokalnie lub spróbuj ponownie za pomocą wykładniczego ponowienia. Musisz zmniejszyć częstotliwość wysyłania żądań.
500 INTERNAL Wystąpił nieoczekiwany błąd wewnętrzny 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 może przetworzyć żądania. Najprawdopodobniej jest to stan przejściowy, który można skorygować, próbując ponownie z wykładniczym opóźnieniem.

Wdrażanie wykładniczego ponawiania

Wykładnicze ponawianie to proces, w którym klient okresowo ponawia próbę nieudanego żądania przez dłuższy czas. Jest to standardowa strategia obsługi błędów w aplikacjach sieciowych. Interfejs API do raportowania został zaprojektowany z myślą o tym, że klienty, które ponawiają nieudane żądania, robią to z użyciem wykładniczego ponowienia. Poza tym, że jest ono „wymagane”, korzystanie z niego zwiększa wydajność wykorzystania przepustowości, zmniejsza liczbę żądań wymaganych do uzyskania pomyślnej odpowiedzi i maksymalizuje przepustowość żądań w równoczesnych środowiskach.

Proces implementacji prostego, wykładniczego ponowienia jest opisany poniżej.

  1. Wyślij żądanie do interfejsu API
  2. otrzyma odpowiedź o błędzie zawierającą kod błędu umożliwiającego ponawianie próby;
  3. Zaczekaj 1 s i random_number_milliseconds s
  4. Ponów prośbę
  5. otrzyma odpowiedź o błędzie zawierającą kod błędu umożliwiającego ponawianie próby;
  6. Zaczekaj 2 s i random_number_milliseconds s
  7. Ponów prośbę
  8. otrzyma odpowiedź o błędzie zawierającą kod błędu umożliwiającego ponawianie próby;
  9. Zaczekaj 4 s i random_number_milliseconds s
  10. Ponów prośbę
  11. otrzyma odpowiedź o błędzie zawierającą kod błędu umożliwiającego ponawianie próby;
  12. Odczekaj 8 s + random_number_milliseconds s
  13. Ponów prośbę
  14. otrzyma odpowiedź o błędzie zawierającą kod błędu umożliwiającego ponawianie próby;
  15. Odczekaj 16 s + random_number_milliseconds s
  16. Ponów prośbę
  17. Jeśli błąd nadal występuje, zatrzymaj go i zarejestruj.

W powyższym procesie random_number_milliseconds jest losową liczbą milisekund równą lub mniejszą od 1000. Jest to konieczne, aby uniknąć pewnych błędów blokady w niektórych równoczesnych implementacjach. Po każdym oczekiwaniu trzeba ponownie określić właściwość random_number_milliseconds.

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

Algorytm kończy działanie, gdy wartość n wynosi 5. Ogranicza się go tylko po to, aby uniemożliwić klientom nieskończone ponawianie prób w nieskończoność, przez co powoduje całkowite opóźnienie (około 32 sekundy) przed uznaniem żądania za „nieodwracalny błąd”.

Poniższy kod w Pythonie to implementacja powyższego procesu usuwania błędów, które wystąpiły 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."