Questo capitolo fornisce una panoramica del modello di errore per le API di Google. Fornisce inoltre agli sviluppatori indicazioni generali su come generare e gestire correttamente gli errori.
Le API di Google utilizzano un semplice modello di errore indipendente dal protocollo, che ci consente di offrire un'esperienza coerente su diverse API, diversi protocolli API (come gRPC o HTTP) e diversi contesti di errore (ad esempio errori asincroni, batch o del flusso di lavoro).
Modello di errore
Il modello di errore per le API di Google è definito logicamente da google.rpc.Status
, un'istanza la cui istanza viene restituita al client quando si verifica un errore dell'API. Il seguente snippet di codice mostra la struttura generale del modello di errore:
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;
}
Poiché la maggior parte delle API di Google utilizza una progettazione basata sulle risorse, la gestione degli errori segue lo stesso principio di progettazione mediante l'utilizzo di un piccolo insieme di errori standard con un elevato numero di risorse. Ad esempio, anziché definire diversi tipi di errori "non trovato", il server utilizza un codice di errore google.rpc.Code.NOT_FOUND
standard e indica al client quale risorsa specifica non è stata trovata. Lo spazio di errore ridotto riduce la complessità della documentazione, offre mappature idiomatiche migliori nelle librerie client e riduce la complessità della logica del client, senza limitare l'inclusione di informazioni strategiche.
Codici di errore
Le API di Google devono utilizzare i codici di errore canonici definiti da
google.rpc.Code
.
Le singole API devono evitare di definire codici di errore aggiuntivi, poiché è molto improbabile che gli sviluppatori scrivano logica per gestire un numero elevato di codici di errore. Per riferimento, gestire una media di tre codici di errore per chiamata API
significa che la maggior parte della logica dell'applicazione deve essere utilizzata solo per la gestione degli errori, il che
non sarebbe una buona esperienza per gli sviluppatori.
Messaggi di errore
Il messaggio di errore dovrebbe aiutare gli utenti a comprendere e risolvere l'errore dell'API in modo semplice e rapido. In generale, tieni presente le seguenti linee guida quando scrivi i messaggi di errore:
- Non dare per scontato che l'utente sia un utente esperto della tua API. Gli utenti possono essere sviluppatori clienti, addetti alle operazioni, personale IT o utenti finali delle app.
- Non dare per scontato che l'utente sappia nulla sull'implementazione del servizio o abbia familiarità con il contesto degli errori (ad esempio l'analisi dei log).
- Se possibile, i messaggi di errore devono essere costruiti in modo che un utente tecnico (ma non necessariamente uno sviluppatore della tua API) possa rispondere all'errore e correggerlo.
- Il messaggio di errore deve essere breve. Se necessario, fornisci un link in cui un lettore confuso possa porre domande, fornire feedback o ottenere ulteriori informazioni che non rientrano correttamente in un messaggio di errore. In caso contrario, utilizza il campo dei dettagli per espanderlo.
Dettagli errore
Le API di Google definiscono un insieme di payload degli errori standard per i dettagli degli errori, che puoi trovare in google/rpc/error_details.proto. Soddisfa le esigenze più comuni in caso di errori dell'API, come errori di quota e parametri non validi. Come i codici di errore, gli sviluppatori dovrebbero usare questi payload standard quando possibile.
Ulteriori tipi di dettagli sugli errori devono essere introdotti solo se possono aiutare il codice dell'applicazione a gestire gli errori. Se le informazioni sull'errore possono essere gestite solo da persone, affidati ai contenuti del messaggio di errore e consenti agli sviluppatori di gestirli manualmente anziché introdurre tipi di dettagli aggiuntivi sull'errore.
Ecco alcuni payload error_details
di esempio:
ErrorInfo
: fornisce informazioni strutturate sugli errori che sono stabili ed estendibili.RetryInfo
: descrive quando i client possono riprovare una richiesta non riuscita, che potrebbe essere restituita il giornoCode.UNAVAILABLE
oCode.ABORTED
QuotaFailure
: descrive l'esito di un controllo della quota, che potrebbe essere restituito il giornoCode.RESOURCE_EXHAUSTED
BadRequest
: descrive le violazioni in una richiesta del cliente, può essere restituito il giornoCode.INVALID_ARGUMENT
Informazioni sull'errore
ErrorInfo
è un tipo speciale di payload di errori. Fornisce informazioni sugli errori stabili ed estensibili su cui possono dipendere gli utenti e le applicazioni.
Ogni ErrorInfo
contiene tre informazioni: un dominio, un motivo e un insieme di metadati dell'errore, come questo esempio.
Per ulteriori informazioni, consulta la definizione di ErrorInfo
.
Per le API di Google, il dominio di errore principale è googleapis.com
e i motivi di errore corrispondenti sono definiti dall'enumerazione google.api.ErrorReason
.
Per ulteriori informazioni, consulta la definizione di google.api.ErrorReason
.
Localizzazione degli errori
Il campo message
in
google.rpc.Status
è rivolto agli sviluppatori e deve essere in inglese.
Se è necessario un messaggio di errore rivolto agli utenti, utilizza google.rpc.LocalizedMessage
come campo dei dettagli. Il campo del messaggio in google.rpc.LocalizedMessage
può essere localizzato, ma assicurati che il campo del messaggio in google.rpc.Status
sia in inglese.
Per impostazione predefinita, il servizio API deve utilizzare le impostazioni internazionali o l'intestazione HTTP Accept-Language
dell'utente autenticato oppure il parametro language_code
nella richiesta per determinare la lingua per la localizzazione.
Mappatura errori
Le API di Google sono accessibili in diversi ambienti di programmazione. In genere, ogni ambiente ha il proprio modo di gestione degli errori. Le seguenti sezioni spiegano come viene mappato il modello di errore negli ambienti di uso comune.
Mappatura HTTP
Sebbene i messaggi proto3 abbiano una codifica JSON nativa, la piattaforma API di Google utilizza uno schema di errore diverso per le API JSON HTTP di Google per motivi di compatibilità con le versioni precedenti.
Schema:
// This message defines the error schema for Google's 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 [Google 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 [Google API Client
// Libraries](https://developers.google.com/api-client-library). It also
// makes the error more readable to developers.
Status error = 1;
}
Esempio (link):
{
"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"
}
}
]
}
}
Mappatura gRPC
Protocolli RPC diversi mappano il modello di errore in modo diverso. Per gRPC, il modello di errore è supportato in modo nativo dal codice generato e dalla libreria di runtime in ogni lingua supportata. Puoi trovare ulteriori informazioni
nella documentazione dell'API di gRPC. Ad esempio, vedi io.grpc.Status
di gRPC Java.
Mappatura libreria client
Le librerie client di Google possono scegliere di visualizzare gli errori in modo diverso a seconda della lingua per essere coerenti con le espressioni idiomatiche consolidate. Ad esempio, la libreria google-cloud-go restituirà un errore che implementa la stessa interfaccia di google.rpc.Status
, mentre google-cloud-java genera un'eccezione.
Gestione degli errori
Di seguito è riportata una tabella contenente tutti i codici di errore gRPC definiti in google.rpc.Code
e una breve descrizione della loro causa. Per gestire un errore, puoi controllare la descrizione del codice di stato restituito e modificare la chiamata di conseguenza.
HTTP | gRPC | Descrizione |
---|---|---|
200 | OK |
Nessun errore. |
400 | INVALID_ARGUMENT |
Il client ha specificato un argomento non valido. Per ulteriori informazioni, controlla il messaggio e i dettagli dell'errore. |
400 | FAILED_PRECONDITION |
La richiesta non può essere eseguita nello stato attuale del sistema, ad esempio l'eliminazione di una directory non vuota. |
400 | OUT_OF_RANGE |
Il client ha specificato un intervallo non valido. |
401 | UNAUTHENTICATED |
La mancata autenticazione della richiesta è dovuta a un token OAuth mancante, non valido o scaduto. |
403 | PERMISSION_DENIED |
Il client non dispone di autorizzazioni sufficienti. Questo può accadere perché il token OAuth non ha gli ambiti corretti, il client non dispone dell'autorizzazione necessaria o l'API non è stata abilitata. |
404 | NOT_FOUND |
Impossibile trovare una risorsa specificata. |
409 | ABORTED |
Conflitto di contemporaneità, ad esempio conflitto di lettura, modifica e scrittura. |
409 | ALREADY_EXISTS |
La risorsa che un client ha cercato di creare esiste già. |
429 | RESOURCE_EXHAUSTED |
Quota di risorse esaurita o vicina alla limitazione della frequenza. Per ulteriori informazioni, il client deve cercare i dettagli dell'errore google.rpc.QuotaFailure. |
499 | CANCELLED |
La richiesta è stata annullata dal client. |
500 | DATA_LOSS |
Perdita di dati non recuperabili o danneggiamento dei dati. Il client deve segnalare l'errore all'utente. |
500 | UNKNOWN |
Errore sconosciuto del server. Solitamente si tratta di un bug del server. |
500 | INTERNAL |
Errore interno del server. Solitamente si tratta di un bug del server. |
501 | NOT_IMPLEMENTED |
Metodo API non implementato dal server. |
502 | N/A | Si è verificato un errore di rete prima di raggiungere il server. In genere si verifica un'interruzione di rete o una configurazione errata. |
503 | UNAVAILABLE |
Servizio non disponibile. In genere il server non è attivo. |
504 | DEADLINE_EXCEEDED |
Scadenza richiesta superata. Ciò si verifica solo se il chiamante imposta una scadenza più breve rispetto alla scadenza predefinita del metodo (ad esempio, la scadenza richiesta non è sufficiente per consentire al server di elaborare la richiesta) e la richiesta non è stata completata entro la scadenza. |
Errori di nuovo tentativo
I client possono riprovare in caso di errori 503 UNAVAILABLE con backoff esponenziale. Il ritardo minimo deve essere di 1 s, a meno che non sia indicato diversamente. La ripetizione predefinita deve essere una volta, a meno che non sia indicato diversamente.
Per gli errori 429 RESOURCE_EXHAUSTED, il client può riprovare al livello superiore con un ritardo minimo di 30 secondi. Questi nuovi tentativi sono utili solo per job in background a lunga esecuzione.
Per tutti gli altri errori, riprova potrebbe non essere applicabile. Innanzitutto, assicurati che la tua richiesta
sia idempotente e consulta
google.rpc.RetryInfo
per istruzioni.
Errori di propagazione
Se il servizio API dipende da altri servizi, non devi propagare ciecamente gli errori da tali servizi ai tuoi client. Quando traduci gli errori, ti consigliamo quanto segue:
- Nascondi i dettagli dell'implementazione e le informazioni riservate.
- Modifica la parte responsabile dell'errore. Ad esempio, un server che riceve un errore
INVALID_ARGUMENT
da un altro servizio deve propagare unINTERNAL
al proprio chiamante.
Riproduzione degli errori
Se non riesci a risolvere gli errori tramite l'analisi dei log e il monitoraggio, prova a riprodurre gli errori con un test semplice e ripetibile. Puoi utilizzare il test per raccogliere ulteriori informazioni per la risoluzione dei problemi che puoi fornire quando contatti l'assistenza tecnica.
Ti consigliamo di utilizzare curl -v
e
Parametri di sistema per riprodurre gli errori
con le API di Google. Insieme possono riprodurre quasi tutte le richieste API di Google e fornire informazioni di debug dettagliate. Per ulteriori informazioni, consulta le rispettive pagine della documentazione per l'API che stai chiamando.
Generazione di errori
Se sei uno sviluppatore di server, devi generare errori con informazioni sufficienti ad aiutare gli sviluppatori client a comprendere e risolvere il problema. Allo stesso tempo, devi conoscere la sicurezza e la privacy dei dati utente ed evitare di divulgare informazioni sensibili nel messaggio e nei dettagli dell'errore, poiché gli errori vengono spesso registrati e potrebbero essere accessibili da altri. Ad esempio, un messaggio di errore come "L'indirizzo IP del client non è nella lista consentita 128.0.0.0/8" espone informazioni sul criterio lato server, che potrebbero non essere accessibili all'utente che ha accesso ai log.
Per generare errori corretti, devi prima avere familiarità con google.rpc.Code
per scegliere il codice di errore più adatto per ogni condizione di errore. Un'applicazione server può controllare più condizioni di errore in parallelo e restituire la prima.
La tabella seguente elenca ciascun codice di errore e un esempio di messaggio di errore valido.
HTTP | gRPC | Esempio di messaggio di errore |
---|---|---|
400 | INVALID_ARGUMENT |
Il campo della richiesta x.y.z è xxx, il valore previsto è [yyy, zzz]. |
400 | FAILED_PRECONDITION |
La risorsa xxx è una directory non vuota, quindi non può essere eliminata. |
400 | OUT_OF_RANGE |
Il parametro "età" non rientra nell'intervallo [0, 125]. |
401 | UNAUTHENTICATED |
Credenziali di autenticazione non valide. |
403 | PERMISSION_DENIED |
Autorizzazione "xxx" negata per la risorsa "yyy". |
404 | NOT_FOUND |
Risorsa "xxx" non trovata. |
409 | ABORTED |
Impossibile acquisire il blocco sulla risorsa "xxx". |
409 | ALREADY_EXISTS |
La risorsa "xxx" esiste già. |
429 | RESOURCE_EXHAUSTED |
Limite quota "xxx" superato. |
499 | CANCELLED |
La richiesta è stata annullata dal client. |
500 | DATA_LOSS |
Vedi nota. |
500 | UNKNOWN |
Vedi nota. |
500 | INTERNAL |
Vedi nota. |
501 | NOT_IMPLEMENTED |
Metodo "xxx" non implementato. |
503 | UNAVAILABLE |
Vedi nota. |
504 | DEADLINE_EXCEEDED |
Vedi nota. |
Payload di errore
Il pacchetto google.rpc
definisce un insieme di payload di errore standard, preferiti rispetto ai payload di errori personalizzati. La tabella seguente elenca ogni codice di errore
e il rispettivo payload di errore standard corrispondente, se applicabile. Consigliamo alle applicazioni avanzate di cercare questi payload di errore in google.rpc.Status
quando gestiscono gli errori.
HTTP | gRPC | Dettaglio errore consigliato |
---|---|---|
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 |