Maneja errores de API

La API de Calendario muestra dos niveles de información de error:

  • Códigos de error y mensajes HTTP en el encabezado
  • Un objeto JSON en el cuerpo de la respuesta con detalles adicionales que pueden ayudarte a determinar cómo controlar el error.

En el resto de esta página, se proporciona una referencia de los errores de Calendario, con algunas guías para manejarlos en tu app.

Implementa la retirada exponencial

En la documentación de las APIs de Cloud, se proporciona una buena explicación de la disminución exponencial y cómo usarla con las APIs de Google.

Errores y acciones sugeridas

En esta sección, se proporciona la representación JSON completa de cada error enumerado y las acciones sugeridas que puedes realizar para controlarlo.

400: Bad Request

Error del usuario. Esto puede significar que no se proporcionó un campo o parámetro obligatorio, que el valor proporcionado no es válido o que la combinación de campos proporcionados no es válida.

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

Acción sugerida: Como se trata de un error permanente, no vuelvas a intentarlo. En su lugar, lee el mensaje de error y cambia tu solicitud según corresponda.

401: Credenciales no válidas

El encabezado de autorización no es válido. El token de acceso que estás usando está vencido o no es válido.

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

Acciones sugeridas:

  • Obtén un nuevo token de acceso con el token de actualización de larga duración.
  • Si esto falla, dirige al usuario a través del flujo de OAuth, como se describe en Autorizar solicitudes con OAuth 2.0.
  • Si ves este mensaje para una cuenta de servicio, verifica que completes correctamente todos los pasos de la página de la cuenta de servicio.

403: Se superó el límite de frecuencia de usuarios

Se alcanzó uno de los límites de Play Console.

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

Acciones sugeridas:

403: Se excedió el límite de frecuencia

El usuario alcanzó la tasa máxima de solicitudes de la API de Calendario de Google por calendario o por usuario autenticado.

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

Acción sugerida: Los errores de rateLimitExceeded pueden mostrar códigos de error 403 o 429. Actualmente, son funcionalmente similares y se deben responder de la misma manera, con la retirada exponencial. Además, asegúrate de que tu app siga las prácticas recomendadas para administrar cuotas.

403: Se superaron los límites de uso del calendario

El usuario alcanzó uno de los límites del Calendario de Google que se implementan para proteger a los usuarios y la infraestructura de Google del comportamiento abusivo.

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

Acciones sugeridas:

403: Prohibido para personas que no son organizadores

La solicitud de actualización del evento intenta establecer una de las propiedades del evento compartido en una copia que no es del organizador. Solo el organizador puede configurar las propiedades compartidas (por ejemplo, guestsCanInviteOthers, guestsCanModify o 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."
 }
}

Acciones sugeridas:

  • Si usas Events: insert, Events: import o Events: update, y tu solicitud no incluye ninguna propiedad compartida, esto equivale a intentar establecerlas en sus valores predeterminados. En su lugar, considera usar Events: patch.
  • Si tu solicitud tiene propiedades compartidas, asegúrate de solo intentar cambiar estas propiedades si actualizas la copia del organizador.

404: No encontrado

No se encontró el recurso especificado. Esto puede suceder en varios casos. Estos son algunos ejemplos:

  • cuando el recurso solicitado (con el ID proporcionado) nunca existió
  • cuando se accede a un calendario al que el usuario no puede acceder

    { "error": { "errors": [ { "domain": "global", "reason": "notFound", "message": "Not Found" } ], "code": 404, "message": "Not Found" } }

Acción sugerida: Usa la retirada exponencial.

409: El identificador solicitado ya existe

Ya existe una instancia con el ID determinado en el almacenamiento.

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

Acción sugerida: Genera un ID nuevo si deseas crear una instancia nueva. De lo contrario, usa la llamada al método update.

409: Conflicto

No se puede ejecutar un elemento por lotes dentro de una operación events.batch debido a un conflicto operativo con otros elementos por lotes solicitados.

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

Acción sugerida: Excluye todos los elementos por lotes que se completaron correctamente y todos los que fallaron definitivamente, y vuelve a intentar los restantes en una events.batch diferente o en las operaciones de un solo evento correspondientes.

410: Ya no está disponible

Los parámetros syncToken o updatedMin ya no son válidos. Este error también puede ocurrir si una solicitud intenta borrar un evento que ya se borró.

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

o

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

o

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "deleted",
    "message": "Resource has been deleted"
   }
  ],
  "code": 410,
  "message": "Resource has been deleted"
 }
}

Acción sugerida: Para los parámetros syncToken o updatedMin, borra la tienda y vuelve a sincronizar. Para obtener más información, consulta Cómo sincronizar recursos de manera eficiente. En el caso de los eventos que ya se borraron, no es necesario que realices ninguna otra acción.

412: Error de condición previa

La ETag proporcionada en el encabezado If-match ya no corresponde a la ETag actual del recurso.

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "conditionNotMet",
    "message": "Precondition Failed",
    "locationType": "header",
    "location": "If-Match",
    }
  ],
  "code": 412,
  "message": "Precondition Failed"
 }
}

Acción sugerida: Vuelve a recuperar la entidad y vuelve a aplicar los cambios. Para obtener más detalles, consulta Cómo obtener versiones específicas de recursos.

429: Demasiadas solicitudes

Se produce un error rateLimitExceeded cuando el usuario envió demasiadas solicitudes en un período determinado.

{
  "error": {
    "errors": [
      {
        "domain": "usageLimits",
        "reason": "rateLimitExceeded",
        "message": "Rate Limit Exceeded"
      }
    ],
    "code": 429,
    "message": "Rate Limit Exceeded"
  }
}

Acción sugerida: Los errores de rateLimitExceeded pueden mostrar códigos de error 403 o 429. Actualmente, son funcionalmente similares y se deben responder de la misma manera, con la retirada exponencial. Además, asegúrate de que tu app siga las prácticas recomendadas para administrar cuotas.

500: Error de backend

Se produjo un error inesperado mientras se procesaba la solicitud.

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "backendError",
    "message": "Backend Error",
   }
  ],
  "code": 500,
  "message": "Backend Error"
 }
}

Acción sugerida: Usa la retirada exponencial.