日历 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 2.0 授权请求中所述,引导用户完成 OAuth 流程。
- 如果您看到的是服务账号的此错误,请检查您是否已 成功完成 服务账号页面中的所有步骤。
403:已超出用户速率限制
已达到开发者控制台中的某个限制。
{
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "userRateLimitExceeded",
"message": "User Rate Limit Exceeded"
}
],
"code": 403,
"message": "User Rate Limit Exceeded"
}
}
建议的操作:
- 确保您的应用遵循 管理配额中的最佳实践。
- 在开发者控制台项目中提高每个用户的配额。
- 如果一位用户代表
Google Workspace 账号的许多用户发出大量请求,请考虑
使用具有全网域授权的服务账号
并设置
quotaUser参数。 - 使用指数退避算法。
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."
}
}
建议的操作:
- 如需详细了解日历用量限额,请参阅 Google Workspace 管理员帮助。
403:非组织者禁止访问
活动更新请求尝试在非组织者的副本中设置共享活动属性之一。共享属性(例如 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:未找到
未找到指定的资源。这可能会在多种情况下发生。 下面是一些示例:
- 当请求的资源(具有提供的 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,否则请使用 update 方法调用。
409:冲突
由于与请求的其他
批处理项存在操作冲突,因此无法执行
events.batch
操作中的批处理项。
{
"error": {
"errors": [
{
"domain": "global",
"reason": "conflict",
"message": "Conflict"
}
],
"code": 409,
"message": "Conflict"
}
}
操作建议: 排除所有成功完成和所有肯定失败的批处理项,然后在不同的 events.batch 或相应的单个事件操作中重试剩余的批处理项。
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."
}
}
或
{
"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"
}
}
操作建议: 使用指数退避算法。