API 오류 처리

Calendar API는 두 가지 수준의 오류 정보를 반환합니다.

  • 헤더의 HTTP 오류 코드 및 메시지
  • 응답 본문의 JSON 객체로, 오류를 처리하는 방법을 결정하는 데 도움이 되는 추가 세부정보가 포함되어 있습니다.

이 페이지의 나머지 부분에서는 Calendar 오류에 관한 참조와 앱에서 이러한 오류를 처리하는 방법에 관한 안내를 제공합니다.

지수 백오프 구현

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

권장 조치:

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 Calendar 한도 중 하나에 도달했습니다.

{
 "error": {
  "errors": [
   {
    "domain": "usageLimits",
    "message": "Calendar usage limits exceeded.",
    "reason": "quotaExceeded"
   }
  ],
  "code": 403,
  "message": "Calendar usage limits exceeded."
 }
}

권장 조치:

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

권장 조치:

  • 이벤트: 삽입, 이벤트: 가져오기 또는 이벤트: 업데이트를 사용 중이고 요청에 공유 속성이 포함되어 있지 않으면 공유 속성을 기본값으로 설정하는 것과 같습니다. 대신 이벤트: 패치를 사용하세요.
  • 요청에 공유 속성이 있는 경우 주최자의 사본을 업데이트하는 경우에만 이러한 속성을 변경하려고 한다고 확인합니다.

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

권장 조치: 지수 백오프를 사용하세요.