API エラーの処理

Calendar API は、次の 2 つのレベルのエラー情報を返します。

  • ヘッダー内の HTTP エラーコードとメッセージ
  • エラーの処理方法の決定に役立つ追加情報を含むレスポンス本文の JSON オブジェクト。

このページの残りの部分では、カレンダー エラーのリファレンスと、アプリでエラーを処理する方法のガイダンスを紹介します。

指数バックオフを実装する

指数バックオフと、Google API での使用方法については、Cloud APIs のドキュメントを参照してください。

エラーと推奨される対応

このセクションでは、表示された各エラーの完全な JSON 表現と、それに対処するために推奨される対応について説明します。

400: Bad Request

ユーザーエラー。必須フィールドまたはパラメータが指定されていないか、指定された値が無効であるか、指定されたフィールドの組み合わせが無効である可能性があります。

{
 "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: 認証情報が無効です

認証ヘッダーが無効です。 お使いのアクセス トークンは有効期限が切れているか、無効です。

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

推奨される対応:

  • 有効期間の長い更新トークンを使用して新しいアクセス トークンを取得します。
  • 失敗した場合は、OAuth 2.0 でのリクエストの承認の説明に従って、OAuth フローをユーザーに案内します。
  • サービス アカウントでこれが表示された場合は、サービス アカウント ページですべての手順が完了していることを確認します。

403: ユーザー レートの上限を超えました

Play Console のいずれかの上限に達しました。

{
 "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: 主催者以外はアクセスできません

イベント更新リクエストで、主催者ではないコピーに共有イベント プロパティのいずれかを設定しようとしています。共有プロパティ(guestsCanInviteOthersguestsCanModifyguestsCanSeeOtherGuests など)は主催者のみが設定できます。

{
 "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: insertEvents: import、または Events: update を使用していて、リクエストに共有プロパティが含まれていない場合、これはデフォルト値に設定しようとするのと同じです。代わりに Events: patch の使用を検討してください。
  • リクエストに共有プロパティが含まれている場合は、主催者のコピーを更新する場合に、これらのプロパティのみを変更しようとしていることを確認してください。

404: 見つかりません

指定されたリソースが見つかりませんでした。これはいくつかの場合に発生することがあります。以下に例を挙げます。

  • リクエストされたリソース(指定された ID を持つ)が存在しない場合
  • ユーザーがアクセスできないカレンダーにアクセスする場合、

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

推奨される対応策: 指数バックオフを使用します。

409: リクエストされた ID はすでに存在します

指定された ID のインスタンスはすでにストレージに存在します。

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

推奨される対応策: 新しいインスタンスを作成する場合は、新しい ID を生成します。それ以外の場合は、update メソッド呼び出しを使用します。

410:消えた

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

or

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

or

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

推奨される対応策: syncToken パラメータまたは updatedMin パラメータの場合は、ストアをワイプして再同期します。詳細については、リソースを効率的に同期するをご覧ください。すでに削除されている予定については、特にご対応いただく必要はありません。

412: 前提条件が失敗しました

If-match ヘッダーで指定された etag がリソースの現在の 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"
 }
}

推奨される対応策: 指数バックオフを使用します。