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

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

После успешной обработки запроса Real Time Reporting API возвращает в теле ответа код статуса 200. В случае ошибки API возвращает в ответе соответствующий код статуса HTTP и сведения о ее причине. Кроме того, в теле ответа подробно описывается, что привело к ошибке. Пример:

{
 "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]"
 }
}

Таблица ошибок

Код Причина Описание Рекомендуемые действия
400 invalidParameter Параметр запроса имеет неверное значение. В полях locationType и location ответа приводятся сведения о недопустимом значении. Прежде чем повторить попытку, устраните проблему. Указанному в ответе параметру должно быть присвоено допустимое значение.
400 badRequest Неверный запрос. Возможно, отсутствует идентификатор родительского элемента, или запрошена недопустимая комбинация параметров и показателей. Прежде чем повторить попытку, устраните проблему. Внесите необходимые изменения в запрос к API.
401 invalidCredentials Неверный или устаревший токен аутентификации. Прежде чем повторить попытку, устраните проблему. Получите новый токен аутентификации.
403 insufficientPermissions У пользователя нет разрешения на работу с объектом, указанным в запросе. Прежде чем повторить попытку, устраните проблему. Получите необходимые разрешения для работы с указанным объектом.
403 dailyLimitExceeded Пользователь превысил дневную квоту для проекта или профиля. Прежде чем повторить попытку, устраните проблему. Вы исчерпали свою дневную квоту. Подробнее об ограничениях и квотах в API
403 userRateLimitExceeded Превышена квота запросов в течение 100 секунд на одного пользователя. Квота по умолчанию – 100 запросов за 100 секунд на каждого пользователя. Ее можно увеличить до 1000 запросов в Google API Console. Попробуйте применить алгоритм экспоненциальной выдержки, чтобы снизить скорость отправки запросов.
403 rateLimitExceeded Превышена квота запросов в течение 100 секунд на один проект. Попробуйте применить алгоритм экспоненциальной выдержки, чтобы снизить скорость отправки запросов.
403 quotaExceeded Достигнуто ограничение в 10 параллельных запросов к Core Reporting API на один профиль. Попробуйте применить алгоритм экспоненциальной выдержки, предварительно дождавшись, пока будет завершен хотя бы один выполняемый запрос.
500 internalServerError Непредвиденная ошибка сервера. Не выполняйте этот запрос повторно.
503 backendError Ошибка сервера. Не выполняйте этот запрос повторно.

Обработка ответов на ошибки 500 и 503

Ошибки 500 и 503 могут возникнуть при высокой нагрузке или сложных запросах. Если вы используете длинный запрос, сократите период, за который требуется получить данные. Кроме того, вы можете применить алгоритм экспоненциальной выдержки. Частота возникновения ошибок зависит от представления (профиля) и объема связанных с ним данных. Поэтому в одном представлении (профиле) запрос может заканчиваться ошибкой 500 или 503, а в другом выполняться корректно.

Реализация алгоритма экспоненциальной выдержки

В рамках алгоритма экспоненциальной выдержки клиент постепенно увеличивает интервалы между попытками выполнить ошибочный запрос. Это стандартная стратегия обработки ошибок в сетевых приложениях является обязательной для клиентов Real Time Reporting 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 и монотонно увеличивается на 1 после каждой итерации, то есть после каждого запроса.

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

Ниже приведен пример реализации этого алгоритма на языке Python для обработки ошибок в методе 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."