處理 API 錯誤

Calendar API 會傳回兩種層級的錯誤資訊:

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

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

實作指數輪詢

Cloud API 說明文件清楚說明瞭指數回退功能,以及如何搭配 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 流程,如「使用 OAuth 2.0 授權要求」一文所述。
  • 如果您看到服務帳戶的這則訊息,請確認您已成功完成服務帳戶頁面中的所有步驟。

403:超過使用者頻率限制

已達開發人員控制台的其中一項限制。

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

建議採取的行動:

403:超過頻率限制

使用者已達到 Google 日曆 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: importEvents: 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 方法呼叫。

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

建議做法:使用指數輪詢