API エラーの処理

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

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

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

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

Cloud APIs のドキュメントには、指数バックオフと Google API での使用方法について詳しく説明されています。

エラーと推奨される対応

このセクションでは、リストに記載されている各エラーの完全な 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: Invalid Credentials

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

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

推奨される対応:

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

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

デベロッパー コンソールのいずれかの上限に達しました。

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

推奨される対応:

  • アプリが割り当ての管理のベスト プラクティスに沿っていることを確認します。
  • デベロッパー コンソールのプロジェクトでユーザーあたりの割り当てを増やします。
  • 1 人のユーザーが Google Workspace アカウントの多くのユーザーに代わって大量のリクエストを行っている場合は、ドメイン全体の委任でサービス アカウントを使用し、quotaUser パラメータを設定することを検討してください。
  • 指数バックオフを使用します。

403: Rate Limit Exceeded

ユーザーが、カレンダーごとまたは認証済みユーザーごとの 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 のインスタンスはストレージにすでに存在します。

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

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

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: 前提条件で失敗しました

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

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