En este capítulo se ofrece una descripción general del modelo de errores de las APIs de Google Distributed Cloud aislado (GDC). También ofrece directrices generales a los desarrolladores sobre cómo generar y gestionar errores correctamente.
Las APIs de GDC usan un modelo de errores sencillo e independiente del protocolo, lo que nos permite ofrecer una experiencia coherente en diferentes APIs, protocolos de APIs (como gRPC o HTTP) y contextos de errores (como errores asíncronos, por lotes o de flujo de trabajo).
Modelo de error
El modelo de errores de las APIs de GDC se define lógicamente mediante google.rpc.Status
, de la que se devuelve una instancia al cliente cuando se produce un error en la API. El siguiente fragmento de código muestra el diseño general del modelo de error:
package google.rpc;
// The `Status` type defines a logical error model that is suitable for
// different programming environments, including REST APIs and RPC APIs.
message Status {
// A simple error code that can be easily handled by the client. The
// actual error code is defined by `google.rpc.Code`.
int32 code = 1;
// A developer-facing human-readable error message in English. It should
// both explain the error and offer an actionable resolution to it.
string message = 2;
// Additional error information that the client code can use to handle
// the error, such as retry info or a help link.
repeated google.protobuf.Any details = 3;
}
Como la mayoría de las APIs de Google usan un diseño de API orientado a recursos, la gestión de errores sigue el mismo principio de diseño y utiliza un pequeño conjunto de errores estándar con un gran número de recursos. Por ejemplo, en lugar de definir diferentes tipos de errores "no encontrado", el servidor usa un código de error google.rpc.Code.NOT_FOUND
estándar e indica al cliente qué recurso específico no se ha encontrado. El espacio de error más pequeño reduce la complejidad de la documentación, ofrece mejores asignaciones idiomáticas en las bibliotecas de cliente y reduce la complejidad de la lógica del cliente sin restringir la inclusión de información útil.
Códigos de error
Las APIs de GDC deben usar los códigos de error canónicos definidos por google.rpc.Code
.
Las APIs individuales deben evitar definir códigos de error adicionales, ya que es muy poco probable que los desarrolladores escriban lógica para gestionar un gran número de códigos de error. Por ejemplo, si se gestionaran una media de tres códigos de error por llamada a la API, la mayor parte de la lógica de la aplicación se dedicaría a la gestión de errores, lo que no sería una buena experiencia para los desarrolladores.
Mensajes de error
El mensaje de error debería ayudar a los usuarios a entender y resolver el error de la API de forma fácil y rápida. En general, ten en cuenta las siguientes directrices al escribir mensajes de error:
- No supongas que el usuario es un experto en tu API. Los usuarios pueden ser desarrolladores de clientes, personal de operaciones, personal de TI o usuarios finales de aplicaciones.
- No supongas que el usuario sabe nada sobre la implementación de tu servicio ni que está familiarizado con el contexto de los errores (como el análisis de registros).
- Cuando sea posible, los mensajes de error deben redactarse de forma que un usuario técnico (pero no necesariamente un desarrollador de tu API) pueda responder al error y corregirlo.
- El mensaje de error debe ser breve. Si es necesario, proporciona un enlace donde un lector confundido pueda hacer preguntas, enviar comentarios u obtener más información que no encaje bien en un mensaje de error. De lo contrario, usa el campo de detalles para ampliar la información.
Detalles de los errores
Las APIs de GDC definen un conjunto de cargas útiles de error estándar para los detalles de los errores, que puedes encontrar en google/rpc/error_details.proto. Cubren las necesidades más habituales en cuanto a errores de API, como fallos de cuota y parámetros no válidos. Al igual que los códigos de error, los desarrolladores deben usar estas cargas útiles estándar siempre que sea posible.
Solo se deben introducir tipos de detalles de error adicionales si pueden ayudar al código de la aplicación a gestionar los errores. Si la información de error solo puede gestionarla un humano, utiliza el contenido del mensaje de error y deja que los desarrolladores lo gestionen manualmente en lugar de introducir tipos de detalles de error adicionales.
Aquí tienes algunos ejemplos de cargas útiles de error_details
:
ErrorInfo
: proporciona información de error estructurada que es estable y extensible.RetryInfo
: describe cuándo pueden volver a intentar los clientes una solicitud fallida. Puede devolverse enCode.UNAVAILABLE
oCode.ABORTED
.QuotaFailure
: describe por qué ha fallado una comprobación de cuota. Se puede devolver enCode.RESOURCE_EXHAUSTED
BadRequest
: Describe las infracciones de una solicitud de un cliente. Se puede devolver enCode.INVALID_ARGUMENT
Información del error
ErrorInfo
es un tipo especial de carga útil de error. Proporciona información de errores estable y extensible en la que pueden confiar tanto los humanos como las aplicaciones.
Cada ErrorInfo
tiene tres elementos de información: un dominio de error, un motivo de error y un conjunto de metadatos de error. Para obtener más información, consulta la definición de ErrorInfo
.
En el caso de las APIs de GDC, el dominio de error principal es googleapis.com
y los motivos de error correspondientes se definen mediante la enumeración google.api.ErrorReason
.
Para obtener más información, consulta la definición de google.api.ErrorReason
.
Localización de errores
El campo message
de
google.rpc.Status
está orientado a los desarrolladores y debe estar en inglés.
Si necesitas mostrar un mensaje de error a los usuarios, usa
google.rpc.LocalizedMessage
en el campo de detalles. Aunque el campo de mensaje de
google.rpc.LocalizedMessage
se puede localizar, asegúrate de que el campo de mensaje de
google.rpc.Status
esté en inglés.
De forma predeterminada, el servicio de la API debe usar la configuración regional del usuario autenticado, el encabezado HTTP Accept-Language
o el parámetro language_code
de la solicitud para determinar el idioma de la localización.
Error de asignación
Se puede acceder a las APIs de GDC en diferentes entornos de programación. Cada entorno suele tener su propia forma de gestionar los errores. En las secciones siguientes se explica cómo se asigna el modelo de errores en los entornos de uso habitual.
Asignación HTTP
Aunque los mensajes de proto3 tienen una codificación JSON nativa, la plataforma de APIs de GDC usa un esquema de errores diferente para las APIs HTTP JSON de GDC por motivos de compatibilidad con versiones anteriores.
Esquema:
// This message defines the error schema for GDC JSON HTTP APIs.
message Error {
// Deprecated. This message is only used by error format v1.
message ErrorProto {}
// This message has the same semantics as `google.rpc.Status`. It uses HTTP
// status code instead of gRPC status code. It has extra fields `status` and
// `errors` for backward compatibility with [GDC API Client
// Libraries](https://developers.google.com/api-client-library).
message Status {
// The HTTP status code that corresponds to `google.rpc.Status.code`.
int32 code = 1;
// This corresponds to `google.rpc.Status.message`.
string message = 2;
// Deprecated. This field is only used by error format v1.
repeated ErrorProto errors = 3;
// This is the enum version for `google.rpc.Status.code`.
google.rpc.Code status = 4;
// This corresponds to `google.rpc.Status.details`.
repeated google.protobuf.Any details = 5;
}
// The actual error payload. The nested message structure is for backward
// compatibility with [GDC API Client
// Libraries](https://developers.google.com/api-client-library). It also
// makes the error more readable to developers.
Status error = 1;
}
Ejemplo:
{
"error": {
"code": 400,
"message": "API key not valid. Please pass a valid API key.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "API_KEY_INVALID",
"domain": "googleapis.com",
"metadata": {
"service": "translate.googleapis.com"
}
}
]
}
}
Asignación de gRPC
Los distintos protocolos RPC asignan el modelo de error de forma diferente. En el caso de gRPC, el modelo de error se admite de forma nativa en el código generado y en la biblioteca de tiempo de ejecución de cada lenguaje admitido. Puedes obtener más información en la documentación de la API de gRPC. Por ejemplo, consulta io.grpc.Status
de gRPC Java.
Asignación de bibliotecas de cliente
Las bibliotecas de cliente de GDC pueden mostrar los errores de forma diferente en cada lenguaje para
ser coherentes con las expresiones establecidas. Por ejemplo, la biblioteca google-cloud-go devolverá un error que implementa la misma interfaz que google.rpc.Status
, mientras que google-cloud-java generará una excepción.
Gestionar errores
En la siguiente tabla se incluyen todos los códigos de error de gRPC definidos en
google.rpc.Code
y una breve descripción de su causa. Para gestionar un error, puedes consultar la descripción del código de estado devuelto y modificar la llamada en consecuencia.
HTTP | gRPC | Descripción |
---|---|---|
200 | OK |
No hay errores. |
400 | INVALID_ARGUMENT |
El cliente especificó un argumento que no es válido. Consulta el mensaje y los detalles del error para obtener más información. |
400 | FAILED_PRECONDITION |
No se puede realizar la solicitud debido al estado actual del sistema, como eliminar un directorio que no está vacío. |
400 | OUT_OF_RANGE |
El cliente especificó un intervalo que no es válido. |
401 | UNAUTHENTICATED |
La solicitud no se ha autenticado porque el token de OAuth ha caducado, no es válido o no se ha encontrado. |
403 | PERMISSION_DENIED |
El cliente no tiene suficientes permisos. Esto puede ocurrir porque el token de OAuth no tiene los permisos adecuados, el cliente no tiene permiso o la API no se ha habilitado. |
404 | NOT_FOUND |
No se ha encontrado un recurso especificado. |
409 | ABORTED |
Se ha producido un conflicto de simultaneidad (por ejemplo, relacionado con acciones de lectura, modificación y escritura). |
409 | ALREADY_EXISTS |
El cliente ha intentado crear un recurso que ya existe. |
429 | RESOURCE_EXHAUSTED |
Se ha agotado la cuota del recurso o se ha alcanzado el límite de frecuencia. El cliente debe buscar el detalle del error google.rpc.QuotaFailure para obtener más información. |
499 | CANCELLED |
El cliente ha cancelado la solicitud. |
500 | DATA_LOSS |
Se han perdido o dañado los datos de forma irrecuperable. El cliente debe informar del error al usuario. |
500 | UNKNOWN |
Se ha producido un error de servidor desconocido. Normalmente, se trata de un error del servidor. |
500 | INTERNAL |
Error de servidor interno. Normalmente, se trata de un error del servidor. |
501 | NOT_IMPLEMENTED |
El servidor no ha implementado el método de API. |
502 | N/A | Se ha producido un error de red antes de llegar al servidor. Normalmente, se trata de una interrupción de la red o de una configuración incorrecta. |
503 | UNAVAILABLE |
Servicio no disponible. Normalmente, el servidor no está operativo. |
504 | DEADLINE_EXCEEDED |
Se ha superado el plazo límite de la solicitud. Esto solo ocurrirá si el llamante establece un plazo que sea inferior al plazo predeterminado del método (es decir, el plazo solicitado no es suficiente para que el servidor procese la solicitud) y la solicitud no se ha completado en ese plazo. |
Reintentar errores
Los clientes pueden reintentar las solicitudes con errores 503 UNAVAILABLE con un tiempo de espera exponencial. El retraso mínimo debe ser de 1 segundo, a menos que se indique lo contrario. La repetición predeterminada de los reintentos debe ser una vez, a menos que se indique lo contrario.
En el caso de los errores 429 RESOURCE_EXHAUSTED, el cliente puede volver a intentarlo en el nivel superior con un retraso mínimo de 30 segundos. Estos reintentos solo son útiles para tareas en segundo plano de larga duración.
En el resto de los casos, puede que no sea posible volver a intentarlo. Primero, asegúrate de que tu solicitud sea idempotente y consulta google.rpc.RetryInfo
para obtener más información.
Propagar errores
Si tu servicio de API depende de otros servicios, no debes propagar ciegamente los errores de esos servicios a tus clientes. Cuando traduzcas errores, te recomendamos lo siguiente:
- Oculta los detalles de implementación y la información confidencial.
- Ajusta la parte responsable del error. Por ejemplo, un servidor que recibe un error
INVALID_ARGUMENT
de otro servicio debe propagar un errorINTERNAL
a su propio llamador.
Reproducir errores
Si no puedes resolver los errores analizando los registros y la monitorización, debes intentar reproducirlos con una prueba sencilla y repetible. Puedes usar la prueba para recoger más información para solucionar problemas, que puedes proporcionar al ponerte en contacto con el equipo de Asistencia técnica.
Te recomendamos que uses
oauth2l
,
curl -v
y
Parámetros del sistema para reproducir errores con las APIs de
GDC. Juntas, pueden reproducir casi todas las solicitudes de la API de GDC y proporcionarte información de depuración detallada. Para obtener más información, consulta las páginas de documentación correspondientes a la API que estés llamando.
Generar errores
Si eres desarrollador de servidores, debes generar errores con suficiente información para ayudar a los desarrolladores de clientes a comprender y resolver el problema. Al mismo tiempo, debes tener en cuenta la seguridad y la privacidad de los datos de los usuarios, y evitar revelar información sensible en el mensaje y los detalles de error, ya que los errores suelen registrarse y otras personas pueden acceder a ellos. Por ejemplo, un mensaje de error como "La dirección IP del cliente no está en la lista de permitidas 128.0.0.0/8" expone información sobre la política del lado del servidor, a la que puede que no tenga acceso el usuario que tiene acceso a los registros.
Para generar errores adecuados, primero debe familiarizarse con google.rpc.Code
para elegir el código de error más adecuado para cada condición de error. Una aplicación de servidor puede comprobar varias condiciones de error en paralelo y devolver la primera.
En la siguiente tabla se muestra cada código de error y un ejemplo de un buen mensaje de error.
HTTP | gRPC | Ejemplo de mensaje de error |
---|---|---|
400 | INVALID_ARGUMENT |
El campo x.y.z de la solicitud es xxx, pero se esperaba uno de los siguientes: [yyy, zzz]. |
400 | FAILED_PRECONDITION |
El recurso xxx es un directorio que no está vacío, por lo que no se puede eliminar. |
400 | OUT_OF_RANGE |
El parámetro "age" está fuera del intervalo [0, 125]. |
401 | UNAUTHENTICATED |
Las credenciales de autenticación no son válidas. |
403 | PERMISSION_DENIED |
Permiso "xxx" denegado en el recurso "yyy". |
404 | NOT_FOUND |
No se ha encontrado el recurso "xxx". |
409 | ABORTED |
No se ha podido obtener el bloqueo del recurso "xxx". |
409 | ALREADY_EXISTS |
El recurso "xxx" ya existe. |
429 | RESOURCE_EXHAUSTED |
Se ha superado el límite de cuota "xxx". |
499 | CANCELLED |
El cliente ha cancelado la solicitud. |
500 | DATA_LOSS |
Consulta la nota. |
500 | UNKNOWN |
Consulta la nota. |
500 | INTERNAL |
Consulta la nota. |
501 | NOT_IMPLEMENTED |
El método "xxx" no se ha implementado. |
503 | UNAVAILABLE |
Consulta la nota. |
504 | DEADLINE_EXCEEDED |
Consulta la nota. |
Cargas útiles de error
El paquete google.rpc
define un conjunto de cargas útiles de error estándar, que son preferibles a las cargas útiles de error personalizadas. En la siguiente tabla se indica cada código de error y su carga útil de error estándar correspondiente, si procede. Recomendamos que las aplicaciones avanzadas busquen estas cargas útiles de error en google.rpc.Status
cuando gestionen errores.
HTTP | gRPC | Detalles de error recomendados |
---|---|---|
400 | INVALID_ARGUMENT |
google.rpc.BadRequest |
400 | FAILED_PRECONDITION |
google.rpc.PreconditionFailure |
400 | OUT_OF_RANGE |
google.rpc.BadRequest |
401 | UNAUTHENTICATED |
google.rpc.ErrorInfo |
403 | PERMISSION_DENIED |
google.rpc.ErrorInfo |
404 | NOT_FOUND |
google.rpc.ResourceInfo |
409 | ABORTED |
google.rpc.ErrorInfo |
409 | ALREADY_EXISTS |
google.rpc.ResourceInfo |
429 | RESOURCE_EXHAUSTED |
google.rpc.QuotaFailure |
499 | CANCELLED |
|
500 | DATA_LOSS |
google.rpc.DebugInfo |
500 | UNKNOWN |
google.rpc.DebugInfo |
500 | INTERNAL |
google.rpc.DebugInfo |
501 | NOT_IMPLEMENTED |
|
503 | UNAVAILABLE |
google.rpc.DebugInfo |
504 | DEADLINE_EXCEEDED |
google.rpc.DebugInfo |