Ответы при ошибках

Стандартные ответы на ошибки

Если запрос API Диспетчера тегов успешен, API возвращает код состояния HTTP 200 вместе с запрошенными данными в теле ответа.

Если при запросе возникает ошибка, API возвращает код состояния HTTP и причину в ответе в зависимости от типа ошибки. Кроме того, тело ответа содержит подробное описание причины ошибки. Вот пример ответа об ошибке:

400 invalidParameter

{
 "error": {
  "errors": [
   {
    "domain": "usageLimits",
    "reason": "accessNotConfigured",
    "message": "Access Not Configured. Please use Google Developers Console to activate the API for your project.",
   }
  ],
  "code": 403,
  "message": "Access Not Configured. Please use Google Developers Console to activate the API for your project."
 }
}

Примечание . Описание может измениться в любой момент, поэтому приложения не должны зависеть от фактического текста описания.

Реализация экспоненциального отката

Экспоненциальная отсрочка — это процесс, при котором клиент периодически повторяет неудачный запрос в течение увеличивающегося промежутка времени. Это стандартная стратегия обработки ошибок для сетевых приложений. API Диспетчера тегов разработан с расчетом на то, что клиенты, решившие повторить неудачные запросы, будут делать это с использованием экспоненциальной задержки. Помимо того, что использование экспоненциальной задержки является «обязательным», оно повышает эффективность использования полосы пропускания, уменьшает количество запросов, необходимых для получения успешного ответа, и максимизирует пропускную способность запросов в параллельных средах.

Порядок реализации простого экспоненциального отката следующий.

  1. Сделайте запрос к API.
  2. Получите ответ об ошибке с кодом ошибки, который можно повторить.
  3. Подождите 1 секунду + random_number_milliseconds секунд.
  4. Повторить запрос.
  5. Получите ответ об ошибке с кодом ошибки, который можно повторить.
  6. Подождите 2 секунды + random_number_milliseconds секунд.
  7. Повторить запрос.
  8. Получите ответ об ошибке с кодом ошибки, который можно повторить.
  9. Подождите 4 секунды + random_number_milliseconds секунд.
  10. Повторить запрос.
  11. Получите ответ об ошибке с кодом ошибки, который можно повторить.
  12. Подождите 8 секунд + random_number_milliseconds секунд.
  13. Повторить запрос.
  14. Получите ответ об ошибке с кодом ошибки, который можно повторить.
  15. Подождите 16 секунд + random_number_milliseconds секунд.
  16. Повторить запрос.
  17. Если вы по-прежнему получаете ошибку, остановитесь и запишите ошибку.

В приведенном выше потоке random_number_milliseconds — это случайное число миллисекунд, меньшее или равное 1000. Это необходимо, чтобы избежать определенных ошибок блокировки в некоторых параллельных реализациях. random_number_milliseconds необходимо переопределять после каждого ожидания.

Примечание . Ожидание всегда равно (2 ^ n ) + random_number_milliseconds , где n — монотонно увеличивающееся целое число, изначально определенное как 0. Переменная n увеличивается на 1 для каждой итерации (каждого запроса).

Алгоритм настроен на завершение, когда n равно 5. Этот предел установлен только для того, чтобы клиенты не могли бесконечно повторять попытки, и приводит к общей задержке около 32 секунд, прежде чем запрос будет считаться «неустранимой ошибкой».

Следующий код Python представляет собой реализацию описанного выше процесса восстановления после ошибок, возникающих в методе makeRequest .

import random
import time
from apiclient.errors import HttpError

def makeRequestWithExponentialBackoff(tagmanager):
  """Wrapper to request Google Tag Manager data with exponential backoff.

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

  Args:
    tagmanager: The tagmanager service object

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

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

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