Как обрабатывать ошибки API

Calendar API возвращает информацию об ошибках двух уровней:

  • Коды ошибок HTTP и сообщения в заголовке
  • Объект JSON в теле ответа с дополнительными сведениями, которые помогут вам определить, как обработать ошибку.

Ниже приведены ошибки Календаря и рекомендации по их устранению в приложении.

Как реализовать экспоненциальную выдержку

В документации по Cloud API подробно описано, что такое экспоненциальная выдержка и как ее использовать с API Google.

Ошибки и рекомендуемые действия

В этом разделе приведено полное представление JSON для каждой ошибки и предлагаемые действия по ее устранению.

400: недопустимый запрос

Ошибка пользователя. Это может означать, что не указано обязательное поле или параметр, указано недопустимое значение или недопустимое сочетание полей.

{
 "error": {
  "errors": [
   {
    "domain": "calendar",
    "reason": "timeRangeEmpty",
    "message": "The specified time range is empty.",
    "locationType": "parameter",
    "location": "timeMax",
   }
  ],
  "code": 400,
  "message": "The specified time range is empty."
 }
}

Рекомендуемое действие. Поскольку это постоянная ошибка, не повторяйте попытку. Прочитайте сообщение об ошибке и измените запрос.

401: Invalid Credentials

Недопустимый заголовок авторизации. Токен доступа, который вы используете, недействителен или срок его действия истек.

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "authError",
    "message": "Invalid Credentials",
    "locationType": "header",
    "location": "Authorization",
   }
  ],
  "code": 401,
  "message": "Invalid Credentials"
 }
}

Рекомендуемые действия:

  • Получите новый токен доступа, используя долгосрочный токен обновления.
  • Если это не удается, направьте пользователя через процесс OAuth, как описано в разделе Авторизация запросов с помощью OAuth 2.0.
  • Если вы видите это сообщение для сервисного аккаунта, убедитесь, что вы выполнили все действия, описанные на странице сервисного аккаунта.

403: User Rate Limit Exceeded (Превышено ограничение на частоту запросов пользователя)

Достигнуто одно из ограничений, установленных в консоли разработчика.

{
 "error": {
  "errors": [
   {
    "domain": "usageLimits",
    "reason": "userRateLimitExceeded",
    "message": "User Rate Limit Exceeded"
   }
  ],
  "code": 403,
  "message": "User Rate Limit Exceeded"
 }
}

Рекомендуемые действия:

403: Превышено ограничение частоты запросов

Пользователь достиг максимальной частоты запросов к Google Calendar API для календаря или аутентифицированного пользователя.

{
 "error": {
  "errors": [
   {
    "domain": "usageLimits",
    "reason": "rateLimitExceeded",
    "message": "Rate Limit Exceeded"
   }
  ],
  "code": 403,
  "message": "Rate Limit Exceeded"
 }
}

Рекомендуемое действие. Ошибки rateLimitExceeded могут возвращать коды ошибок 403 или 429. В настоящее время они функционально схожи, и на них следует реагировать одинаково, используя экспоненциальную выдержку. Кроме того, убедитесь, что ваше приложение соответствует рекомендациям из раздела Управление квотами.

403: превышены лимиты на использование Календаря

Пользователь достиг одного из ограничений Google Календаря, установленных для защиты пользователей и инфраструктуры Google от злоупотреблений.

{
 "error": {
  "errors": [
   {
    "domain": "usageLimits",
    "message": "Calendar usage limits exceeded.",
    "reason": "quotaExceeded"
   }
  ],
  "code": 403,
  "message": "Calendar usage limits exceeded."
 }
}

Рекомендуемые действия:

403: Forbidden for non-organizer

В запросе на обновление мероприятия предпринимается попытка задать одно из общих свойств мероприятия в копии, которая не принадлежит организатору. Общие свойства (например, guestsCanInviteOthers, guestsCanModify или guestsCanSeeOtherGuests) может задавать только организатор.

{
 "error": {
  "errors": [
   {
    "domain": "calendar",
    "reason": "forbiddenForNonOrganizer",
    "message": "Shared properties can only be changed by the organizer of the event."
   }
  ],
  "code": 403,
  "message": "Shared properties can only be changed by the organizer of the event."
 }
}

Рекомендуемые действия:

  • Если вы используете метод Events: insert, Events: import или Events: update и ваш запрос не содержит общих свойств, это равносильно попытке установить для них значения по умолчанию. Рекомендуем использовать метод Events: patch.
  • Если в запросе есть общие свойства, убедитесь, что вы пытаетесь изменить их только при обновлении копии организатора.

404: Not Found

Указанный ресурс не найден. Это может произойти в нескольких случаях. Вот несколько примеров:

  • когда запрошенный ресурс (с указанным идентификатором) никогда не существовал;
  • при попытке открыть календарь, к которому у пользователя нет доступа;

    { "error": { "errors": [ { "domain": "global", "reason": "notFound", "message": "Not Found" } ], "code": 404, "message": "Not Found" } }

Рекомендуемое действие. Используйте экспоненциальную выдержку.

409: запрошенный идентификатор уже существует

Экземпляр с указанным идентификатором уже существует в хранилище.

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "duplicate",
    "message": "The requested identifier already exists."
   }
  ],
  "code": 409,
  "message": "The requested identifier already exists."
 }
}

Рекомендуемое действие. Если вы хотите создать новый экземпляр, сгенерируйте новый идентификатор. В противном случае используйте вызов метода update.

409: Conflict

Элемент пакета в операции events.batch не может быть выполнен из-за конфликта с другими запрошенными элементами пакета.

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "conflict",
    "message": "Conflict"
   }
  ],
  "code": 409,
  "message": "Conflict"
 }
}

Рекомендуемое действие. Исключите все успешно завершенные и все определенно неудачные пакетные элементы и повторите попытку с оставшимися в другой пакетной операции events.batch или соответствующих отдельных операциях.

410: Gone

Параметры syncToken и updatedMin больше не поддерживаются. Эта ошибка также может возникнуть, если в запросе предпринята попытка удалить мероприятие, которое уже было удалено.

{
 "error": {
  "errors": [
   {
    "domain": "calendar",
    "reason": "fullSyncRequired",
    "message": "Sync token is no longer valid, a full sync is required.",
    "locationType": "parameter",
    "location": "syncToken",
    }
  ],
  "code": 410,
  "message": "Sync token is no longer valid, a full sync is required."
 }
}

или

{
 "error": {
  "errors": [
   {
    "domain": "calendar",
    "reason": "updatedMinTooLongAgo",
    "message": "The requested minimum modification time lies too far in the past.",
    "locationType": "parameter",
    "location": "updatedMin",
   }
  ],
  "code": 410,
  "message": "The requested minimum modification time lies too far in the past."
 }
}

или

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "deleted",
    "message": "Resource has been deleted"
   }
  ],
  "code": 410,
  "message": "Resource has been deleted"
 }
}

Рекомендуемое действие. Для параметров syncToken или updatedMin очистите хранилище и выполните повторную синхронизацию. Подробнее о том, как эффективно синхронизировать ресурсы… Если вы уже удалили мероприятие, никаких дополнительных действий не требуется.

412: Precondition Failed

Тег etag, указанный в заголовке If-match, больше не соответствует текущему тегу etag ресурса.

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "conditionNotMet",
    "message": "Precondition Failed",
    "locationType": "header",
    "location": "If-Match",
    }
  ],
  "code": 412,
  "message": "Precondition Failed"
 }
}

Рекомендуемое действие: повторно извлеките объект и примените изменения. Подробнее о том, как получить определенные версии ресурсов…

429: слишком много запросов

Ошибка rateLimitExceeded возникает, когда пользователь отправляет слишком много запросов за определенный период времени.

{
  "error": {
    "errors": [
      {
        "domain": "usageLimits",
        "reason": "rateLimitExceeded",
        "message": "Rate Limit Exceeded"
      }
    ],
    "code": 429,
    "message": "Rate Limit Exceeded"
  }
}

Рекомендуемое действие. Ошибки rateLimitExceeded могут возвращать коды ошибок 403 или 429. В настоящее время они функционально схожи, и на них следует реагировать одинаково, используя экспоненциальную выдержку. Кроме того, убедитесь, что ваше приложение соответствует рекомендациям из раздела Управление квотами.

500: ошибка бэкенда

При обработке запроса произошла непредвиденная ошибка.

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "backendError",
    "message": "Backend Error",
   }
  ],
  "code": 500,
  "message": "Backend Error"
 }
}

Рекомендуемое действие. Используйте экспоненциальную выдержку.