Maneja errores de API

La API de Calendar devuelve dos niveles de información de error:

  • Códigos y mensajes de error HTTP en el encabezado
  • 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 del Calendario, con algunas orientaciones sobre cómo controlarlos en tu app.

Implementa la retirada exponencial

En la documentación de las APIs de Cloud, se explica bien el retroceso exponencial y cómo usarlo con las APIs de Google.

Errores y acciones sugeridas

En esta sección, se proporciona la representación JSON completa de cada error que se menciona 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: Debido a que este es 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 venció 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, dirígelo a través del flujo de OAuth, como se describe en Autoriza solicitudes con OAuth 2.0.
  • Si ves este mensaje para una cuenta de servicio, verifica que hayas completado correctamente todos los pasos de la página de la cuenta de servicio.

403: Se superó el límite de frecuencia del usuario

Se alcanzó uno de los límites de Developer 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 del 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 devolver códigos de error 403 o 429. Actualmente, son funcionalmente similares y se debe responder de la misma manera, usando la retirada exponencial. Además, asegúrate de que tu app siga las prácticas recomendadas de administración de cuotas.

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

El usuario alcanzó uno de los límites del Calendario de Google establecidos 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 quienes 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 la del organizador. El organizador es el único que puede establecer 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 intentar cambiar estas propiedades solo si estás actualizando la copia del organizador.

404: No se encontró

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 proporcionado 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 quieres 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 de 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 definitivamente fallaron, y vuelve a intentar con los restantes en diferentes operaciones de events.batch o en las operaciones de eventos únicos 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 sincronizarla. Para obtener más información, consulta Cómo sincronizar recursos de manera eficiente. En el caso de los eventos ya borrados, no es necesario realizar 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 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 devolver códigos de error 403 o 429. Actualmente, son funcionalmente similares y se debe responder de la misma manera, usando la retirada exponencial. Además, asegúrate de que tu app siga las prácticas recomendadas de administración de 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.