Questa guida spiega come l'API Data Manager gestisce e comunica gli errori. Comprendere la struttura e il significato degli errori dell'API è fondamentale per creare applicazioni robuste in grado di gestire correttamente i problemi, dall'input non valido alla mancata disponibilità temporanea del servizio.
L'API Data Manager segue il modello di errore standard delle API di Google, basato
su codici di stato gRPC. Ogni risposta API che genera un errore include un oggetto Status con:
- Un codice di errore numerico.
- Un messaggio di errore.
- Dettagli di errore aggiuntivi facoltativi.
Codici di errore canonici
L'API Data Manager utilizza un insieme di codici di errore canonici definiti da gRPC e HTTP. Questi codici forniscono un'indicazione di alto livello del tipo di errore. Dovresti sempre controllare prima questo codice per comprendere la natura fondamentale del problema.
Per maggiori dettagli su questi codici, consulta la Guida alla progettazione delle API - Codici di errore.
Gestisci gli errori
Segui questi passaggi quando una richiesta non va a buon fine:
Controlla il codice di errore per trovare il tipo di errore.
- Se utilizzi gRPC, il codice di errore si trova nel
codecampo diStatus. Se utilizzi una libreria client, potrebbe generare un tipo specifico di eccezione corrispondente al codice di errore. Ad esempio, la libreria client per Java genera un'eccezionecom.google.api.gax.rpc.InvalidArgumentExceptionse il codice di errore èINVALID_ARGUMENT. - Se utilizzi REST, il codice di errore si trova nella risposta di errore in
error.statuse il codice di stato HTTP corrispondente si trova inerror.code.
- Se utilizzi gRPC, il codice di errore si trova nel
Controlla il payload dei dettagli standard per il codice di errore. I payload dei dettagli standard sono un insieme di messaggi per gli errori delle API di Google. Forniscono i dettagli degli errori in modo strutturato e coerente. Ogni errore dell'API Data Manager può avere più messaggi di payload dei dettagli standard. Le librerie client dell'API Data Manager hanno metodi helper per ottenere i payload dei dettagli standard da un errore.
Indipendentemente dal codice di errore, ti consigliamo di controllare e registrare i payload
ErrorInfo,RequestInfo,Help, eLocalizedMessage.ErrorInfocontiene informazioni che potrebbero non essere presenti in altri payload.RequestInfocontiene l'ID richiesta, utile se devi contattare l'assistenza.HelpeLocalizedMessagecontengono link e altri dettagli per aiutarti a risolvere l'errore.
Inoltre, il payload
BadRequestè utile per gli erroriINVALID_ARGUMENTperché fornisce informazioni sui campi che hanno causato l'errore.
Payload dei dettagli standard
I payload dei dettagli standard più comuni per l'API Data Manager sono:
BadRequest
Controlla il BadRequest payload quando una richiesta non va a buon fine con
INVALID_ARGUMENT (codice di stato HTTP 400).
Un messaggio BadRequest indica che la richiesta conteneva campi con valori errati o che mancava un valore per un campo obbligatorio. Controlla l'elenco field_violations in BadRequest per trovare i campi con errori. Ogni voce field_violations contiene informazioni utili per correggere l'errore:
fieldLa posizione del campo nella richiesta, utilizzando una sintassi del percorso in camel case.
Se un percorso punta a un elemento in un elenco (un campo
repeated), il relativo indice viene visualizzato tra parentesi quadre ([...]) dopo il nome dell'elenco.Ad esempio,
destinations[0].operating_account.account_idè l'account_idinoperating_accountdel primo elemento nell'destinationselenco.descriptionUna spiegazione del motivo per cui il valore ha causato un errore.
reasonL'enumerazione
ErrorReason, ad esempioINVALID_HEX_ENCODINGoINVALID_CURRENCY_CODE.
Esempi di BadRequest
Di seguito è riportata una risposta di esempio per un errore INVALID_ARGUMENT con un messaggio BadRequest. Le field_violations mostrano che l'errore è un accountId che non è un numero. Il valore field destinations[0].login_account.account_id mostra che
accountId con una violazione del campo si trova in login_account del primo elemento
nell'elenco destinations.
{
"error": {
"code": 400,
"message": "There was a problem with the request.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "INVALID_ARGUMENT",
"domain": "datamanager.googleapis.com",
"metadata": {
"requestId": "t-a8896317-069f-4198-afed-182a3872a660"
}
},
{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "t-a8896317-069f-4198-afed-182a3872a660"
},
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "destinations[0].login_account.account_id",
"description": "String is not a valid number.",
"reason": "INVALID_NUMBER_FORMAT"
}
]
}
]
}
}
Di seguito è riportata un'altra risposta di esempio da un errore INVALID_ARGUMENT con un messaggio BadRequest. In questo caso, l'elenco field_violations mostra due errori:
Il primo
eventha un valore che non è codificato in esadecimale sul secondo identificatore utente dell'evento.Il secondo
eventha un valore che non è codificato in esadecimale sul terzo identificatore utente dell'evento.
{
"error": {
"code": 400,
"message": "There was a problem with the request.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "INVALID_ARGUMENT",
"domain": "datamanager.googleapis.com",
"metadata": {
"requestId": "t-6bc8fb83-d648-4942-9c49-2604276638d8"
}
},
{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "t-6bc8fb83-d648-4942-9c49-2604276638d8"
},
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "events.events[0].user_data.user_identifiers[1]",
"description": "The HEX encoded value is malformed.",
"reason": "INVALID_HEX_ENCODING"
},
{
"field": "events.events[1].user_data.user_identifiers[2]",
"description": "The HEX encoded value is malformed.",
"reason": "INVALID_HEX_ENCODING"
}
]
}
]
}
}
RequestInfo
Controlla il RequestInfo payload ogni volta che una richiesta non va a buon fine. Un RequestInfo contiene il request_id che identifica in modo univoco la tua richiesta API.
{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "t-4490c640-dc5d-4c28-91c1-04a1cae0f49f"
}
Quando registri gli errori o contatti l'assistenza, assicurati di includere l'ID richiesta per facilitare la diagnosi dei problemi.
ErrorInfo
Controlla il messaggio ErrorInfo per recuperare informazioni aggiuntive che
potrebbero non essere acquisite negli altri payload dei dettagli standard. Il payload ErrorInfo contiene una mappa metadata con informazioni sull'errore.
Ad esempio, ecco l'ErrorInfo per un errore PERMISSION_DENIED causato dall'utilizzo delle credenziali per un progetto Google Cloud in cui l'API Data Manager non è abilitata. L'ErrorInfo fornisce informazioni aggiuntive sull'errore, ad esempio:
- Il progetto associato alla richiesta, in
metadata.consumer. - Il nome del servizio, in
metadata.serviceTitle. - L'URL in cui è possibile abilitare il servizio, in
metadata.activationUrl.
{
"error": {
"code": 403,
"message": "Data Manager API has not been used in project PROJECT_NUMBER before or it is disabled. Enable it by visiting https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "SERVICE_DISABLED",
"domain": "googleapis.com",
"metadata": {
"consumer": "projects/PROJECT_NUMBER",
"service": "datamanager.googleapis.com",
"containerInfo": "PROJECT_NUMBER",
"serviceTitle": "Data Manager API",
"activationUrl": "https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER"
}
},
...
]
}
}
Help e LocalizedMessage
Controlla i payload Help e LocalizedMessage per ottenere link alla
documentazione e messaggi di errore localizzati che ti aiutano a comprendere e correggere l'
errore.
Ad esempio, ecco l'Help e il LocalizedMessage per un errore PERMISSION_DENIED causato dall'utilizzo delle credenziali per un progetto Google Cloud in cui l'API Data Manager non è abilitata. Il payload Help mostra l'URL in cui è possibile abilitare il servizio e il LocalizedMessage contiene una descrizione dell'errore.
{
"error": {
"code": 403,
"message": "Data Manager API has not been used in project PROJECT_NUMBER before or it is disabled. Enable it by visiting https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.LocalizedMessage",
"locale": "en-US",
"message": "Data Manager API has not been used in project PROJECT_NUMBER before or it is disabled. Enable it by visiting https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."
},
{
"@type": "type.googleapis.com/google.rpc.Help",
"links": [
{
"description": "Google API Console API activation",
"url": "https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER"
}
]
},
...
]
}
}
Accedi ai dettagli dell'errore
Se utilizzi una delle librerie client, utilizza i metodi helper per ottenere i payload dei dettagli standard.
.NET
try {
// Send API request
}
catch (Grpc.Core.RpcException rpcException)
{
Console.WriteLine($"Exception encountered: {rpcException.Message}");
var statusDetails =
Google.Api.Gax.Grpc.RpcExceptionExtensions.GetAllStatusDetails(
rpcException
);
foreach (var detail in statusDetails)
{
if (detail is Google.Rpc.BadRequest)
{
Google.Rpc.BadRequest badRequest = (Google.Rpc.BadRequest)detail;
foreach (
BadRequest.Types.FieldViolation? fieldViolation in badRequest.FieldViolations
)
{
// Access attributes such as fieldViolation!.Reason and fieldViolation!.Field
}
}
else if (detail is Google.Rpc.RequestInfo)
{
Google.Rpc.RequestInfo requestInfo = (Google.Rpc.RequestInfo)detail;
string requestId = requestInfo.RequestId;
// Log the requestId...
}
else if (detail is Google.Rpc.ErrorInfo)
{
Google.Rpc.ErrorInfo errorInfo = (Google.Rpc.ErrorInfo)detail;
// Log the errorInfo.Reason and errorInfo.Metadata...
// Log the details in the 'Metadata' map...
foreach (
KeyValuePair<String, String> metadataEntry in errorInfo.Metadata
)
{
// Log the metadataEntry.Key and metadataEntry.Value...
}
}
else
{
// ...
}
}
}
Java
try {
// Send API request
} catch (com.google.api.gax.rpc.InvalidArgumentException invalidArgumentException) {
// Gets the standard BadRequest payload from the exception.
BadRequest badRequest = invalidArgumentException.getErrorDetails().getBadRequest();
for (int i = 0; i < badRequest.getFieldViolationsCount(); i++) {
FieldViolation fieldViolation = badRequest.getFieldViolations(i);
// Access attributes such as fieldViolation.getField() and fieldViolation.getReason()
}
// Gets the standard RequestInfo payload from the exception.
RequestInfo requestInfo = invalidArgumentException.getErrorDetails().getRequestInfo();
if (requestInfo != null) {
String requestId = requestInfo.getRequestId();
// Log the requestId...
}
} catch (com.google.api.gax.rpc.ApiException apiException) {
// Fallback exception handler for other types of ApiException.
// Gets the standard ErrorInfo payload from the exception.
ErrorInfo errorInfo = apiException.getErrorDetails().getErrorInfo();
// Log the 'reason' and 'domain'...
// Log the details in the 'metadata' map...
for (Entry<String, String> metadataEntry : errorInfo.getMetadataMap().entrySet()) {
// Log the metadataEntry key and value...
}
// Gets the standard RequestInfo payload from the exception.
RequestInfo requestInfo = invalidArgumentException.getErrorDetails().getRequestInfo();
if (requestInfo != null) {
String requestId = requestInfo.getRequestId();
// Log the requestId...
}
...
}
Best practice per la gestione degli errori
Per creare applicazioni resilienti, implementa le seguenti best practice.
- Esamina i dettagli dell'errore
- Cerca sempre uno dei payload dei dettagli standard come
BadRequest. Ogni payload dei dettagli standard contiene informazioni utili per comprendere la causa dell'errore. - Distinguere gli errori del client da quelli del server
Determina se l'errore è causato da un problema con l'implementazione (il client) o con l'API (il server).
- Errori del client: codici come
INVALID_ARGUMENT,NOT_FOUND,PERMISSION_DENIED,FAILED_PRECONDITION,UNAUTHENTICATED. Questi richiedono modifiche alla richiesta o allo stato/alle credenziali dell'applicazione. Non riprovare a inviare la richiesta senza risolvere il problema. - Errori del server: codici come
UNAVAILABLE,INTERNAL,DEADLINE_EXCEEDED,UNKNOWN. Questi suggeriscono un problema temporaneo con il servizio API.
- Errori del client: codici come
- Implementa una strategia di nuovi tentativi
Determina se è possibile riprovare a inviare la richiesta in caso di errore e utilizza una strategia di nuovi tentativi.
- Riprova solo per gli errori del server temporanei come
UNAVAILABLE,DEADLINE_EXCEEDED,INTERNAL,UNKNOWNeABORTED. - Utilizza un algoritmo di backoff esponenziale per attendere periodi di tempo sempre più lunghi tra i nuovi tentativi. In questo modo, eviti di sovraccaricare un servizio già sotto stress. Ad esempio, attendi 1 secondo, poi 2 secondi, poi 4 secondi, continuando fino a un numero massimo di nuovi tentativi o al tempo di attesa totale.
- Aggiungi una piccola quantità casuale di "jitter" ai ritardi di backoff per evitare il problema del "thundering herd", in cui molti client riprovano contemporaneamente.
- Riprova solo per gli errori del server temporanei come
- Registra in modo completo
Registra la risposta di errore completa, inclusi tutti i payload dei dettagli standard, in particolare l'ID richiesta. Queste informazioni sono essenziali per il debug e la segnalazione di problemi all'assistenza Google, se necessario.
- Fornisci feedback agli utenti
In base ai codici e ai messaggi nei payload dei dettagli standard, fornisci un feedback chiaro e utile agli utenti della tua applicazione. Ad esempio, anziché dire semplicemente "Si è verificato un errore", puoi dire "Mancava l'ID transazione" o "Non è stato trovato l'ID account della destinazione".
Se segui queste linee guida, puoi diagnosticare e gestire in modo efficace gli errori restituiti dall'API Data Manager, ottenendo applicazioni più stabili e di facile utilizzo.