Neste capítulo, apresentamos uma visão geral do modelo de erro para as APIs do Google Distributed Cloud com isolamento físico (GDC). Também oferece orientações gerais para os desenvolvedores sobre como gerar e lidar corretamente com erros.
As APIs do GDC usam um modelo de erro simples e independente de protocolo, o que nos permite oferecer uma experiência consistente em diferentes APIs, diferentes protocolos de API (como gRPC ou HTTP) e diferentes contextos de erro (como erros assíncronos, em lote ou de fluxo de trabalho).
Modelo de erro
O modelo de erro para as APIs do GDC é definido logicamente por
google.rpc.Status,
uma instância que é retornada ao cliente quando ocorre um erro de API. O snippet de código a seguir mostra o projeto geral do modelo de erro:
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 a maioria das APIs do Google usa um design orientado a recursos, o tratamento de erros segue o mesmo princípio do design, usando um pequeno conjunto de erros padrão com uma grande quantidade de recursos. Por exemplo, em vez de definir diferentes tipos de erros "não encontrado", o servidor usa um código do erro google.rpc.Code.NOT_FOUND padrão e informa ao cliente qual recurso específico não foi encontrado. O
espaço com erro menor reduz a complexidade da documentação, oferece melhores
mapeamentos idiomáticos nas bibliotecas de cliente e reduz a complexidade da lógica do cliente
sem restringir a inclusão de informações acionáveis.
Códigos de erro
As APIs do GDC precisam usar os códigos de erro canônicos definidos por
google.rpc.Code.
As APIs individuais precisam evitar a definição de códigos dos erros adicionais, porque
é muito improvável que os desenvolvedores escrevam uma lógica para lidar com um grande número de códigos
dos erros. Para referência, lidar com uma média de três códigos de erro por chamada de API
significaria que a maior parte da lógica do aplicativo seria apenas para tratamento de erros, o que não
seria uma boa experiência para o desenvolvedor.
Mensagens de erro
A mensagem de erro deve ajudar os usuários a entender e resolver o erro da API de maneira fácil e rápida. Em geral, considere as diretrizes a seguir ao escrever mensagens de erro:
- Não presuma que os usuários sejam especialistas na sua API. Eles podem ser desenvolvedores de clientes, pessoal de operações, equipe de TI ou usuários finais de aplicativos.
- Não presuma que o usuário saiba de tudo sobre a implementação do seu serviço ou esteja familiarizado com o contexto dos erros (como análise de registro).
- Quando possível, as mensagens de erro precisam ser criadas de maneira que um usuário técnico, não necessariamente um desenvolvedor da sua API, possa responder ao erro e corrigi-lo.
- Mantenha a mensagem de erro resumida. Se necessário, forneça um link em que um leitor com dúvidas possa fazer perguntas, dar feedback ou obter mais informações que não se encaixam em uma mensagem de erro. Caso contrário, use o campo de detalhes para expandir.
Detalhes do erro
As APIs do GDC definem um conjunto de payloads de erro padrão para detalhes de erro, que podem ser encontrados em google/rpc/error_details.proto. Eles abrangem as necessidades mais comuns de erros de API, como falha de cota e parâmetros inválidos. Assim como os códigos de erro, os desenvolvedores precisam usar esses payloads padrão sempre que possível.
Os tipos de detalhes de erros adicionais apenas serão introduzidos se puderem ajudar o código do aplicativo a lidar com os erros. Se as informações de erro exigirem intervenção humana, confie no conteúdo da mensagem de erro e deixe os desenvolvedores lidarem com isso manualmente, em vez de introduzir outros tipos de detalhes de erros.
Veja alguns exemplos de payloads error_details:
ErrorInfo: fornece informações de erro estruturadas que são estáveis e extensíveis.RetryInfo: descreve quando os clientes podem repetir uma solicitação com falha. Pode ser retornado emCode.UNAVAILABLEouCode.ABORTEDQuotaFailure: descreve como uma verificação de cota falhou. Pode ser retornado emCode.RESOURCE_EXHAUSTEDBadRequest: descreve violações em uma solicitação do cliente. Pode ser retornado emCode.INVALID_ARGUMENT
Informações do erro
ErrorInfo é um tipo especial de payload de erro. Ele fornece informações de erro estáveis e
extensíveis que podem ser usadas por humanos e aplicativos.
Cada ErrorInfo tem três informações: um domínio de erro, um motivo de erro e um conjunto de metadados de erro. Para mais informações, consulte a definição de ErrorInfo.
Para as APIs do GDC, o domínio de erro principal é googleapis.com, e os
motivos de erro correspondentes são definidos pelo tipo enumerado google.api.ErrorReason.
Para mais informações, consulte a
definição de google.api.ErrorReason.
Localização de erros
O campo message em google.rpc.Status é voltado para desenvolvedores e precisa estar em inglês.
Se for necessária uma mensagem de erro para o usuário, use google.rpc.LocalizedMessage como campo de detalhes. Embora o campo de mensagem em google.rpc.LocalizedMessage possa ser localizado, verifique se o campo de mensagem em google.rpc.Status está em inglês.
Por padrão, o serviço de API deve usar a localidade do usuário autenticado ou o cabeçalho HTTP Accept-Language ou o parâmetro language_code na solicitação para determinar o idioma da localização.
Mapeamento de erros
As APIs do GDC podem ser acessadas em diferentes ambientes de programação. Cada ambiente geralmente tem uma forma própria de tratamento de erros. As seções a seguir explicam como o modelo de erro é mapeado em ambientes usados com frequência.
Mapeamento de HTTP
Embora as mensagens proto3 tenham codificação JSON nativa, a plataforma da API GDC usa um esquema de erro diferente para as APIs HTTP JSON do GDC por motivos de compatibilidade com versões 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;
}
Exemplo:
{
"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"
}
}
]
}
}
Mapeamento de gRPC
Cada protocolo RPC mapeia o modelo de erro de maneira diferente. Para gRPC, o modelo de erro é compatível de maneira nativa com o código gerado e com a biblioteca de tempo de execução em cada linguagem aceita. Para mais informações,
veja a documentação da API do gRPC. Por exemplo, consulte io.grpc.Status
do Java gRPC.
Mapeamento da biblioteca de cliente
As bibliotecas de cliente do GDC podem optar por mostrar erros de maneira diferente por linguagem para
serem consistentes com as expressões estabelecidas. Por exemplo, a biblioteca google-cloud-go retorna um erro que implementa a mesma interface de google.rpc.Status, enquanto google-cloud-java gerará uma exceção.
Tratar erros
A tabela a seguir contém todos os códigos de erro do gRPC definidos em
google.rpc.Code
e uma breve descrição da causa. Para lidar com um erro, você pode verificar a descrição do código de status retornado e modificar a chamada de acordo com ela.
| HTTP | gRPC | Descrição |
|---|---|---|
| 200 | OK |
Sem erro. |
| 400 | INVALID_ARGUMENT |
O cliente especificou um argumento inválido. Verifique a mensagem de erro e os detalhes do erro para mais informações. |
| 400 | FAILED_PRECONDITION |
A solicitação não pode ser executada no estado atual do sistema atual, como excluir um diretório que não está vazio. |
| 400 | OUT_OF_RANGE |
O cliente especificou um intervalo inválido. |
| 401 | UNAUTHENTICATED |
Solicitação não autenticada devido ao token OAuth ausente, inválido ou expirado. |
| 403 | PERMISSION_DENIED |
O cliente não tem permissão suficiente. Isso pode acontecer porque o token OAuth não tem os escopos certos, o cliente não tem permissão ou a API não foi ativada. |
| 404 | NOT_FOUND |
Um recurso especificado não foi encontrado. |
| 409 | ABORTED |
Conflito de simultaneidade, como leitura-modificação-gravação. |
| 409 | ALREADY_EXISTS |
O recurso que um cliente tentou criar já existe. |
| 429 | RESOURCE_EXHAUSTED |
Excedeu a cota de recursos ou está perto de atingir a limitação de taxa. O cliente deve procurar detalhes do erro google.rpc.QuotaFailure para mais informações. |
| 499 | CANCELLED |
Solicitação cancelada pelo cliente. |
| 500 | DATA_LOSS |
Perda de dados irrecuperável ou dados corrompidos. O cliente deve comunicar o erro ao usuário. |
| 500 | UNKNOWN |
Erro de servidor desconhecido. Geralmente, um bug do servidor. |
| 500 | INTERNAL |
Erro interno do servidor. Geralmente, um bug do servidor. |
| 501 | NOT_IMPLEMENTED |
Método da API não implementado pelo servidor. |
| 502 | N/A | Ocorreu um erro de rede antes de chegar ao servidor. Normalmente, uma falha de rede ou uma configuração incorreta. |
| 503 | UNAVAILABLE |
Serviço indisponível. Geralmente, o servidor está desativado. |
| 504 | DEADLINE_EXCEEDED |
O prazo de solicitação foi excedido. Isso acontecerá somente se o chamador definir um prazo menor que o prazo padrão do método (ou seja, o prazo solicitado não é suficiente para o servidor processar a solicitação) e a solicitação não for concluída dentro do prazo. |
Erros ao tentar novamente
Os clientes podem tentar novamente em 503 erros de DESCONTOÁVEIS com retirada exponencial. O atraso mínimo deve ser de um segundo, a menos que seja documentado de outra maneira. A repetição padrão precisa ser uma vez, a menos que esteja documentado de outra forma.
Para erros 429 de RESOURCE_EXHAUSTED, o cliente pode tentar novamente no nível superior com atraso mínimo de 30 segundos. Essas novas tentativas são úteis somente para jobs em execução longa em segundo plano.
Para todos os outros erros, a nova tentativa pode não ser aplicável. Primeiro, verifique se a solicitação
é idempotente e veja
google.rpc.RetryInfo
para orientação.
Propagar erros
Se o serviço da API depende de outros serviços, não convém propagar precipitadamente os erros desses serviços para os seus clientes. Ao traduzir erros, sugerimos o seguinte:
- Oculte detalhes de implementação e informações confidenciais.
- Ajuste a parte responsável pelo erro. Por exemplo, um servidor que recebe um erro
INVALID_ARGUMENTde outro serviço deve propagar umINTERNALpara o próprio autor da chamada.
Reproduzir erros
Se não for possível resolver erros com a análise de registros e monitoramento, tente reproduzir os erros com um teste simples e repetível. Use o teste para coletar mais informações sobre solução de problemas. Entre em contato com o suporte técnico e forneça essas informações.
Recomendamos que você use
oauth2l,
curl -v e
parâmetros do sistema para reproduzir erros com
as APIs do GDC. Juntos, eles podem reproduzir quase todas as solicitações de API do GDC
e fornecer informações de depuração detalhadas. Para mais informações, consulte as
respectivas páginas de documentação da API que você está chamando.
Gerar erros
Se você é um desenvolvedor de servidores, precisa gerar erros com informações suficientes para ajudar os desenvolvedores de clientes a entender e resolver o problema. Ao mesmo tempo, é preciso estar ciente da segurança e da privacidade dos dados do usuário e evitar divulgar informações sensíveis na mensagem de erro e nos detalhes do erro, já que os erros geralmente são registrados e podem ser acessados por outras pessoas. Por exemplo, uma mensagem de erro como "O endereço IP do cliente não está na lista de permissões 128.0.0.0/8" expõe informações sobre a política do lado do servidor, que pode não ser acessível para o usuário que tem acesso aos registros.
Para gerar erros adequados, primeiro você precisa se familiarizar com google.rpc.Code para escolher o código do erro mais adequado para cada condição de erro. Um aplicativo do servidor pode verificar várias condições de erro em paralelo e retornar a primeira.
A tabela a seguir lista cada código do erro e um exemplo de uma boa mensagem.
| HTTP | gRPC | Exemplo de mensagem de erro |
|---|---|---|
| 400 | INVALID_ARGUMENT |
O campo de solicitação xyz é xxx, mas o esperado é [yyy, zzz]. |
| 400 | FAILED_PRECONDITION |
O recurso xxx é um diretório que não está vazio, portanto, não pode ser excluído. |
| 400 | OUT_OF_RANGE |
A "idade" do parâmetro está fora do intervalo [0, 125]. |
| 401 | UNAUTHENTICATED |
Credenciais de autenticação inválidas. |
| 403 | PERMISSION_DENIED |
Permissão "xxx" negada no recurso "yyy". |
| 404 | NOT_FOUND |
O recurso "xxx" não foi encontrado. |
| 409 | ABORTED |
Não foi possível adquirir o bloqueio no recurso 'xxx. |
| 409 | ALREADY_EXISTS |
O recurso "xxx" já existe. |
| 429 | RESOURCE_EXHAUSTED |
Limite de cota "xxx" excedido. |
| 499 | CANCELLED |
Solicitação cancelada pelo cliente. |
| 500 | DATA_LOSS |
Consulte a observação. |
| 500 | UNKNOWN |
Consulte a observação. |
| 500 | INTERNAL |
Consulte a observação. |
| 501 | NOT_IMPLEMENTED |
Método "xxx" não implementado. |
| 503 | UNAVAILABLE |
Consulte a observação. |
| 504 | DEADLINE_EXCEEDED |
Consulte a observação. |
Payloads de erro
O pacote google.rpc define um conjunto de payloads de erro padrão, que são preferenciais aos payloads de erro personalizados. A tabela a seguir lista cada código do erro
e o payload de erro padrão correspondente, se aplicável. Recomendamos que os aplicativos
avançados procurem esses payloads de erro em google.rpc.Status ao
processar os erros.
| HTTP | gRPC | Detalhe de erro recomendado |
|---|---|---|
| 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 |