Questa guida spiega come l'API Data Manager gestisce e comunica gli errori. Comprendere la struttura e il significato degli errori API è fondamentale per creare applicazioni robuste in grado di gestire correttamente i problemi, dall'input non valido all'indisponibilità temporanea del servizio.
L'API Data Manager segue il modello di errore standard delle API di Google, basato
sui 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.
- Facoltativi, ulteriori dettagli sull'errore.
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 generale del tipo di errore. Devi 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 campo
codediStatus. 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 uncom.google.api.gax.rpc.InvalidArgumentExceptionse il codice di errore èINVALID_ARGUMENT. - Se utilizzi REST, il codice di errore si trova nella risposta di errore all'indirizzo
error.status, mentre lo stato HTTP corrispondente si trova all'indirizzoerror.code.
- Se utilizzi gRPC, il codice di errore si trova nel campo
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 di 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,HelpeLocalizedMessage.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, i payload
BadRequest,QuotaFailureeRetryInfosono utili per codici di errore specifici:- Se il codice di stato è
INVALID_ARGUMENT, controlla il payloadBadRequestper informazioni sui campi che hanno causato l'errore. - Se il codice di stato è
RESOURCE_EXHAUSTED, controlla i payloadQuotaFailureeRetryInfoper informazioni sulle quote e un consiglio sul ritardo dei tentativi.
Payload di dettagli standard
I payload standard dei dettagli più comuni per l'API Data Manager sono:
BadRequest
Controlla il payload BadRequest 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 scoprire quali campi contengono errori. Ogni voce field_violations
contiene informazioni per aiutarti a correggere l'errore:
fieldLa posizione del campo nella richiesta, utilizzando una sintassi del percorso in camel case.
Se un percorso punta a un elemento di un elenco (un campo
repeated), il relativo indice viene mostrato tra parentesi quadre ([...]) dopo il nome dell'elenco.Ad esempio,
destinations[0].operating_account.account_idè ilaccount_idinoperating_accountdel primo elemento dell'elencodestinations.descriptionUna spiegazione del motivo per cui il valore ha causato un errore.
reasonL'enumerazione
ErrorReason, ad esempioINVALID_HEX_ENCODINGoINVALID_CURRENCY_CODE.
Esempi di BadRequest
Ecco una risposta di esempio per un errore INVALID_ARGUMENT con un messaggio BadRequest. field_violations mostra che l'errore è un accountId che non è un
numero. Il valore field destinations[0].login_account.account_id mostra
accountId con una violazione del campo si trova in login_account del primo elemento
dell'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"
}
]
}
]
}
}
Ecco un altro esempio di risposta a 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 nel secondo identificatore utente dell'evento.Il secondo
eventha un valore che non è codificato in esadecimale nel 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"
}
]
}
]
}
}
QuotaFailure e RetryInfo
Controlla i payload QuotaFailure e RetryInfo quando una richiesta non va a buon fine
con RESOURCE_EXHAUSTED (codice di stato HTTP 429).
Un messaggio QuotaFailure indica che una risorsa è esaurita
(ad esempio, hai superato la quota) o che un sistema è sovraccarico. Esamina
l'elenco di violations per determinare quali quote sono state superate.
L'errore potrebbe contenere anche un messaggio RetryInfo, che indica un valore
retry_delay consigliato per riprovare a inviare la richiesta.
RequestInfo
Controlla il payload RequestInfo ogni volta che una richiesta non va a buon fine. Un RequestInfo
contiene l'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 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 di dettagli standard. Il payload ErrorInfo
contiene una mappa metadata con informazioni sull'errore.
Ad esempio, ecco il ErrorInfo per un errore PERMISSION_DENIED causato dall'utilizzo di credenziali per un progetto Google Cloud in cui l'API Data Manager non è abilitata. Il ErrorInfo fornisce ulteriori informazioni sull'errore, ad esempio:
- Il progetto associato alla richiesta, in
metadata.consumer. - Il nome del servizio, in
metadata.serviceTitle. - L'URL in cui è possibile attivare 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.developers.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.developers.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 Help e 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 attivare il servizio e 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.developers.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.developers.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 developers console API activation",
"url": "https://console.developers.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER"
}
]
},
...
]
}
}
Accedere 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.QuotaFailure)
{
Google.Rpc.QuotaFailure quotaFailure = (Google.Rpc.QuotaFailure)detail;
foreach (
Google.Rpc.QuotaFailure.Types.Violation violation in quotaFailure.Violations
)
{
// Access attributes such as violation.Subject and violation.QuotaId
}
}
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.QuotaFailureException quotaFailureException) {
// Gets the standard QuotaFailure payload from the exception.
QuotaFailure quotaFailure = quotaFailureException.getErrorDetails().getQuotaFailure();
for (int i = 0; i < quotaFailure.getViolationsCount(); i++) {
QuotaFailure.Violation violation = quotaFailure.getViolations(i);
// Access attributes such as violation.getSubject() and violation.getQuotaId()
}
// Gets the standard RequestInfo payload from the exception.
RequestInfo requestInfo = quotaFailureException.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.
...
}
Best practice per la gestione degli errori
Per creare applicazioni resilienti, implementa le seguenti best practice.
- Esaminare i dettagli dell'errore
- Cerca sempre uno dei payload di dettagli standard, ad esempio
BadRequest. Ogni payload dettagli standard contiene informazioni per aiutarti a 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 ripetizione dei tentativi
Determina se è possibile riprovare a eseguire l'operazione in caso di errore e utilizza una strategia di ripetizione.
- Riprova solo in caso di errori del server temporanei come
UNAVAILABLE,DEADLINE_EXCEEDED,INTERNAL,UNKNOWNeABORTED. - Utilizza un algoritmo di backoff esponenziale per attendere periodi sempre più lunghi tra i tentativi. In questo modo si evita 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 tentativi o tempo di attesa totale.
- Aggiungi un piccolo importo casuale di "jitter" ai ritardi di backoff per evitare il problema del "gregge fragoroso" in cui molti client riprovano contemporaneamente.
- Riprova solo in caso di errori del server temporanei come
- Registrare 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.
- Fornire feedback degli utenti
In base ai codici e ai messaggi nei payload di dettagli standard, fornisci un feedback chiaro e utile agli utenti della tua applicazione. Ad esempio, anziché dire semplicemente "Si è verificato un errore", puoi dire "Manca l'ID transazione" o "L'ID account della destinazione non è stato trovato".
Se segui queste linee guida, puoi diagnosticare e gestire in modo efficace gli errori restituiti dall'API Data Manager, ottenendo applicazioni più stabili e facili da usare.