處理 API 錯誤

Google 日曆 API 會傳回兩層錯誤資訊:

  • 標頭中的 HTTP 錯誤代碼和訊息
  • 回應主體中的 JSON 物件,內含可協助您判斷如何處理錯誤的其他詳細資料。

本頁面其餘部分提供 Google 日曆錯誤的參考資料,並說明如何在應用程式中處理這些錯誤。

實作指數輪詢

Google Cloud Storage 說明文件說明瞭指數輪詢延遲,以及如何搭配 Google API 使用這項功能。

錯誤和建議動作

本節提供每個列出錯誤的完整 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:憑證無效

授權標頭無效。 您使用的存取權杖已過期或無效。

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

建議採取的動作:

  • 使用長期更新權杖取得新的存取權杖。
  • 如果失敗,請按照「使用 OAuth 2.0 授權要求」一文所述,引導使用者完成 OAuth 流程。
  • 如果服務帳戶發生這個錯誤,請確認您已順利完成服務帳戶頁面中的所有步驟。

403:User Rate Limit Exceeded (超過使用者頻率限制)

已達 Google Cloud 控制台的其中一個上限。

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

建議採取的動作:

403:超過頻率限制

使用者已達到日曆 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: 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;否則請使用 events.update 方法。

409:Conflict (衝突)

由於與其他要求的批次項目發生作業衝突,events.batch 作業中的批次項目無法執行。

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

建議動作:移除已完成和失敗的項目,然後在不同的 events.batch 或對應的單一事件作業中,重試其餘項目。

410:已移除

syncTokenupdatedMin 參數已失效。如果要求嘗試刪除已刪除的事件,也可能發生這個錯誤。

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

建議採取的動作:針對 syncTokenupdatedMin 參數,清除商店並重新同步。詳情請參閱「有效率地同步處理資源」。如果活動已刪除,則無須採取任何行動。

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

建議做法:使用指數輪詢