Questo capitolo fornisce una panoramica del modello di errore per le API Google Distributed Cloud air-gapped (GDC). Fornisce inoltre indicazioni generali agli sviluppatori su come generare e gestire correttamente gli errori.
Le API GDC utilizzano un modello di errore semplice e indipendente dal protocollo, che ci consente di offrire un'esperienza coerente tra diverse API, diversi protocolli API (come gRPC o HTTP) e diversi contesti di errore (come errori asincroni, batch o del flusso di lavoro).
Modello di errore
Il modello di errore per le API GDC è definito logicamente da
google.rpc.Status
,
di cui viene restituita un'istanza al client quando si verifica un errore 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 orientata alle risorse, la gestione degli errori
segue lo stesso principio di progettazione utilizzando un piccolo insieme di errori standard con un
gran 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 comunica al client quale risorsa specifica non è stata trovata. Lo spazio di errore più piccolo riduce la complessità della documentazione, consente mappature idiomatiche migliori nelle librerie client e riduce la complessità della logica del client senza limitare l'inclusione di informazioni utili.
Codici di errore
Le API GDC 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 una logica per gestire un numero elevato di codici di errore. A titolo di riferimento, la gestione di una media di tre codici di errore per chiamata API
implicherebbe che la maggior parte della logica dell'applicazione sarebbe dedicata alla gestione degli errori, il che
non sarebbe una buona esperienza per gli sviluppatori.
Messaggi di errore
Il messaggio di errore deve aiutare gli utenti a comprendere e risolvere l'errore API in modo semplice e rapido. In generale, tieni presente le seguenti linee guida quando scrivi messaggi di errore:
- Non dare per scontato che l'utente sia un esperto della tua API. Gli utenti potrebbero essere sviluppatori client, personale operativo, personale IT o utenti finali di app.
- Non dare per scontato che l'utente sappia qualcosa dell'implementazione del tuo servizio o che abbia familiarità con il contesto degli errori (ad esempio l'analisi dei log).
- Quando possibile, i messaggi di errore devono essere strutturati in modo che un utente tecnico (ma non necessariamente uno sviluppatore della tua API) possa rispondere all'errore e correggerlo.
- Mantieni breve il messaggio di errore. Se necessario, fornisci un link in cui un lettore confuso possa porre domande, fornire feedback o ottenere maggiori informazioni che non si adattano perfettamente a un messaggio di errore. In caso contrario, utilizza il campo dei dettagli per espandere.
Dettagli errore
Le API GDC definiscono un insieme di payload di errore standard per i dettagli degli errori, che puoi trovare in google/rpc/error_details.proto. Questi coprono le esigenze più comuni per gli errori API, come l'esaurimento della quota e i parametri non validi. Come per i codici di errore, gli sviluppatori devono utilizzare questi payload standard ogni volta che è possibile.
I tipi di dettagli aggiuntivi sull'errore 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, fai affidamento sui contenuti del messaggio di errore e lascia che gli sviluppatori lo gestiscano manualmente anziché introdurre ulteriori tipi di dettagli sugli errori.
Ecco alcuni payload error_details
di esempio:
ErrorInfo
: fornisce informazioni strutturate sugli errori che sono sia stabili che estensibili.RetryInfo
: descrive quando i client possono riprovare a inviare una richiesta non riuscita, può essere restituito suCode.UNAVAILABLE
oCode.ABORTED
QuotaFailure
: descrive il motivo per cui un controllo della quota non è riuscito. Può essere restituito suCode.RESOURCE_EXHAUSTED
BadRequest
: Descrive le violazioni in una richiesta client, può essere restituito suCode.INVALID_ARGUMENT
Informazioni sull'errore
ErrorInfo
è un tipo speciale di payload di errore. Fornisce informazioni sugli errori stabili ed
estensibili su cui possono fare affidamento sia gli utenti che le applicazioni.
Ogni ErrorInfo
contiene tre informazioni: un dominio di errore, un motivo
dell'errore e un insieme di metadati dell'errore. Per ulteriori informazioni, consulta la definizione di
ErrorInfo
.
Per le API GDC, 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 all'utente, utilizza
google.rpc.LocalizedMessage
come campo dei dettagli. Sebbene il campo del messaggio in
google.rpc.LocalizedMessage
possa essere localizzato, assicurati che il campo del messaggio in
google.rpc.Status
sia in inglese.
Per impostazione predefinita, il servizio API deve utilizzare le impostazioni internazionali dell'utente autenticato o l'intestazione HTTP Accept-Language
o il parametro language_code
nella richiesta per determinare la lingua per la localizzazione.
Mappatura degli errori
Le API GDC sono accessibili in diversi ambienti di programmazione. Ogni ambiente in genere ha il proprio modo di gestione degli errori. Le sezioni seguenti spiegano come viene mappato il modello di errore negli ambienti di uso comune.
Mappatura HTTP
Mentre i messaggi proto3 hanno la codifica JSON nativa, la piattaforma API GDC utilizza uno schema di errore diverso per le API HTTP JSON GDC per motivi di compatibilità con le versioni precedenti.
Schema:
// 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;
}
Esempio:
{
"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"
}
}
]
}
}
Mapping 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 linguaggio supportato. Per saperne di più,
consulta la documentazione dell'API gRPC. Ad esempio, vedi io.grpc.Status
di gRPC Java.
Mappatura della libreria client
Le librerie client GDC possono scegliere di mostrare gli errori in modo diverso per lingua per
essere coerenti con le espressioni idiomatiche consolidate. Ad esempio, la libreria
google-cloud-go
restituisce un errore che implementa la stessa interfaccia di
google.rpc.Status
,
mentre
google-cloud-java
genera un'eccezione.
Gestisci gli errori
La tabella seguente contiene tutti i codici di errore gRPC definiti in
google.rpc.Code
e una breve descrizione della relativa 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 maggiori informazioni, controlla il messaggio di errore 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. Ciò può accadere perché il token OAuth non dispone degli ambiti corretti, il client non dispone dell'autorizzazione o l'API non è stata abilitata. |
404 | NOT_FOUND |
Una risorsa specificata non è stata trovata. |
409 | ABORTED |
Conflitto di concorrenza, 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. In genere si tratta di un bug del server. |
500 | INTERNAL |
Errore interno del server. In genere si tratta di un bug del server. |
501 | NOT_IMPLEMENTED |
Metodo API non implementato dal server. |
502 | N/D | Si è verificato un errore di rete prima di raggiungere il server. In genere 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 di quella predefinita del metodo (ovvero la scadenza richiesta non è sufficiente per consentire al server di elaborare la richiesta) e la richiesta non è stata completata entro la scadenza. |
Riprova errori
I client possono riprovare in caso di errori 503 UNAVAILABLE con backoff esponenziale. Il ritardo minimo deve essere di 1 secondo, a meno che non sia documentato diversamente. Il numero di ripetizioni dei tentativi deve essere una sola volta, se non diversamente documentato.
Per gli errori 429 RESOURCE_EXHAUSTED, il client può riprovare a un livello superiore con un ritardo minimo di 30 secondi. Questi tentativi sono utili solo per i job in background a esecuzione prolungata.
Per tutti gli altri errori, il nuovo tentativo potrebbe non essere applicabile. Innanzitutto, assicurati che la tua richiesta
sia idempotente e consulta
google.rpc.RetryInfo
per indicazioni.
Propagare gli errori
Se il tuo servizio API dipende da altri servizi, non devi propagare ciecamente gli errori di questi servizi ai tuoi clienti. Quando traduci gli errori, ti consigliamo di procedere nel seguente modo:
- Nascondi i dettagli di 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.
Riproduci gli errori
Se non riesci a risolvere gli errori tramite l'analisi dei log e il monitoraggio, devi provare a riprodurli 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
oauth2l
e
curl -v
e
Parametri di sistema per riprodurre gli errori con
le API GDC. Insieme possono riprodurre quasi tutte le richieste API GDC
e fornire informazioni di debug dettagliate. Per saperne di più, consulta le pagine di documentazione
relative all'API che stai chiamando.
Genera errori
Se sei uno sviluppatore di server, devi generare errori con informazioni sufficienti per aiutare gli sviluppatori di client a comprendere e risolvere il problema. Allo stesso tempo, devi essere consapevole della sicurezza e della privacy dei dati utente ed evitare di divulgare informazioni sensibili nel messaggio di errore e nei dettagli dell'errore, poiché gli errori vengono spesso registrati e potrebbero essere accessibili ad 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 appropriati, devi prima familiarizzare con google.rpc.Code
per scegliere il codice di errore più adatto a ogni condizione di errore. Un'applicazione
server può controllare più condizioni di errore in parallelo e restituire
la prima.
La seguente tabella elenca ciascun codice di errore e un esempio di un buon messaggio di errore.
HTTP | gRPC | Esempio di messaggio di errore |
---|---|---|
400 | INVALID_ARGUMENT |
Il campo della richiesta x.y.z è xxx, è previsto uno dei seguenti valori: [yyy, zzz]. |
400 | FAILED_PRECONDITION |
La risorsa xxx è una directory non vuota, pertanto non può essere eliminata. |
400 | OUT_OF_RANGE |
Il parametro "age" non è compreso 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 della risorsa "xxx". |
409 | ALREADY_EXISTS |
La risorsa "xxx" esiste già. |
429 | RESOURCE_EXHAUSTED |
Limite di 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 |
Il 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, che sono
preferibili ai payload di errore personalizzati. La tabella seguente elenca ogni codice di errore
e il relativo payload di errore standard, se applicabile. Consigliamo alle applicazioni avanzate di cercare questi payload di errore in google.rpc.Status
quando gestiscono gli errori.
HTTP | gRPC | Dettagli dell'errore consigliati |
---|---|---|
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 |