En esta guía, se explica cómo la API de Data Manager controla y comunica los errores. Comprender la estructura y el significado de los errores de la API es fundamental para compilar aplicaciones sólidas que puedan controlar los problemas de forma correcta, desde entradas no válidas hasta la falta de disponibilidad temporal del servicio.
La API de Data Manager sigue el modelo de error estándar de la API de Google, que se basa
en los códigos de estado de gRPC. Cada respuesta de la API que genera un
error incluye un objeto Status con lo siguiente:
- Un código de error numérico.
- Es un mensaje de error.
- Detalles adicionales del error (opcional).
Códigos de error canónicos
La API de Data Manager usa un conjunto de códigos de error canónicos definidos por gRPC y HTTP. Estos códigos proporcionan una indicación de alto nivel del tipo de error. Siempre debes verificar este código primero para comprender la naturaleza fundamental del problema.
Para obtener más detalles sobre estos códigos, consulta la Guía de diseño de APIs: Códigos de error.
Modelo de falla rápida
La API de Data Manager usa un modelo de falla rápida. Si una solicitud contiene errores estructurales o si algún registro no supera la validación de un campo obligatorio, toda la solicitud falla y la API no procesa ninguno de los datos de esa solicitud.
Comparación con el modelo de falla parcial
El modelo de falla rápida difiere del modelo de falla parcial en algunas otras APIs de Google, como la API de Google Ads y la API de Campaign Manager 360. En el modelo de falla parcial, una solicitud se completa correctamente incluso si algunos registros tienen errores, y la respuesta contiene detalles del error para los registros con errores.
Aunque la falla parcial puede ser conveniente, conlleva riesgos significativos, ya que el modelo de falla parcial no te alerta de forma proactiva sobre los errores, sino que debes verificar de forma explícita si hay errores en cada respuesta. Esto puede ocultar problemas importantes, ya que una solicitud se realiza correctamente incluso si la API rechaza muchos o incluso todos los registros de la solicitud. Si una parte significativa de los registros de una solicitud tiene errores, pero no inspeccionas la respuesta, es posible que no te enteres de los problemas generalizados con tus datos y que solo los descubras días o semanas después, cuando los resultados acumulados no se alineen con tus expectativas.
El modelo de falla rápida evita estos problemas, ya que te alerta sobre problemas con tus datos o la integración de inmediato para que puedas tomar las medidas adecuadas.
Verifica si hay errores de falla rápida con validateOnly
La mayoría de las solicitudes de transferencia y eliminación admiten un campo validateOnly. Cuando
estableces validateOnly en true, la API de Data Manager ejecuta las mismas verificaciones de validación
básicas que para una solicitud normal, pero no transfiere ni quita ningún dato.
- Si la solicitud tiene errores, falla con la misma respuesta de error que obtendrías de una solicitud normal.
- Si la solicitud pasa la validación, se realiza correctamente. La respuesta incluye cualquier
fieldWarningspara los campos opcionales, como una solicitud normal.
Utiliza validateOnly para:
- Prueba una integración nueva o actualizada sin afectar tus datos en tiempo real.
- Confirma que la corrección resuelva el error antes de volver a enviar la solicitud.
Soluciona errores
Sigue estos pasos cuando falle una solicitud:
Verifica el código de error para encontrar el tipo de error.
- Si usas gRPC, el código de error se encuentra en el campo
codedeStatus. Si usas una biblioteca cliente, es posible que arroje un tipo específico de excepción que corresponda al código de error. Por ejemplo, la biblioteca cliente para Java arroja unacom.google.api.gax.rpc.InvalidArgumentExceptionsi el código de error esINVALID_ARGUMENT. - Si usas REST, el código de error se encuentra en la respuesta de error en
error.status, y el estado HTTP correspondiente se encuentra enerror.code.
- Si usas gRPC, el código de error se encuentra en el campo
Verifica la carga útil de detalles estándar para ver el código de error. Las cargas útiles de detalles estándar son un conjunto de mensajes para errores de las APIs de Google. Te brindan detalles de los errores de una manera estructurada y coherente. Cada error de la API de Data Manager puede tener varios mensajes de carga útil de detalles estándar. Las bibliotecas cliente de la API de Data Manager tienen métodos auxiliares para obtener las cargas útiles de detalles estándar de un error.
Independientemente del código de error, te recomendamos que verifiques y registres las cargas útiles de
ErrorInfo,RequestInfo,HelpyLocalizedMessage.ErrorInfotiene información que podría no estar en otras cargas útiles.RequestInfotiene el ID de la solicitud, que es útil si necesitas comunicarte con el equipo de asistencia.HelpyLocalizedMessagecontienen vínculos y otros detalles para ayudarte a solucionar el error.
Además, la carga útil de
BadRequestes útil para los errores deINVALID_ARGUMENT, ya que proporciona información sobre qué campos causaron el error.
Advertencias de transferencia
La API de Data Manager acepta la mayor cantidad posible de solicitudes de transferencia. Si incluyes datos que no son obligatorios, los errores de validación de esos campos no harán que la solicitud falle. Por ejemplo, si a un artículo del carrito le falta un ID del producto del comercio, la API procesa el resto de la solicitud y devuelve una advertencia.
Una respuesta de transferencia correcta (código de estado HTTP 200) incluye estas advertencias
en una lista fieldWarnings. Cada entrada es un objeto FieldWarning con los
siguientes campos:
fieldEs la ubicación del campo en la solicitud, en la sintaxis de la ruta de acceso en minúsculas con guiones bajos.
Si una ruta de acceso apunta a un elemento de una lista (un campo
repeated), su índice se muestra entre corchetes ([...]) después del nombre de la lista.Por ejemplo,
events.events[0].cart_data.items[0].merchant_product_ididentifica una advertencia relacionada con el primer artículo de los datos del carrito del primer evento de la solicitud.descriptionEs una explicación de por qué el valor proporcionado causó una advertencia.
reasonEs el valor de la enumeración
WarningReasonque identifica el tipo de advertencia.
Ejemplo con FieldWarning
A continuación, se muestra una respuesta de ejemplo para una solicitud de transferencia correcta que contiene una advertencia porque faltaba un ID del producto del comercio para uno de los artículos del carrito.
{
"requestId": "126365e1-16d0-4c81-9de9-f362711e250a",
"fieldWarnings": [
{
"field": "events.events[0].cart_data.items[0].merchant_product_id",
"description": "The merchant product ID is missing in the cart item.",
"reason": "WARNING_REASON_CART_DATA_ITEM_MERCHANT_PRODUCT_ID_MISSING"
}
]
}
Cargas útiles de detalles estándar
Estas son las cargas útiles de detalles estándar más comunes para la API de Data Manager:
BadRequest
Verifica la carga útil BadRequest cuando una solicitud falla con
INVALID_ARGUMENT (código de estado HTTP 400).
Un mensaje BadRequest indica que la solicitud tenía campos con valores incorrectos o que
faltaba un valor para un campo obligatorio. Consulta la lista field_violations en el
BadRequest para saber qué campos tienen errores. Cada entrada de field_violations
tiene información para ayudarte a corregir el error:
fieldEs la ubicación del campo en la solicitud, en la sintaxis de ruta de acceso de minúsculas con guiones bajos.
Si una ruta de acceso apunta a un elemento de una lista (un campo
repeated), su índice se muestra entre corchetes ([...]) después del nombre de la lista.Por ejemplo,
destinations[0].operating_account.account_ides elaccount_iden eloperating_accountdel primer elemento de la listadestinations.descriptionUna explicación de por qué el valor causó un error.
reasonEs la enumeración
ErrorReason, comoINVALID_HEX_ENCODINGoINVALID_CURRENCY_CODE.
Ejemplos de BadRequest
Esta es una respuesta de ejemplo para un error INVALID_ARGUMENT con un mensaje
BadRequest. El field_violations muestra que el error es un accountId que no es un
número. El valor destinations[0].login_account.account_id de field muestra que el accountId con un incumplimiento de campo se encuentra en el login_account del primer elemento de la lista 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"
}
]
}
]
}
}
Aquí tienes otra respuesta de ejemplo de un error INVALID_ARGUMENT con un
mensaje BadRequest. En este caso, la lista field_violations muestra dos
errores:
El primer
eventtiene un valor que no está codificado en formato hexadecimal en el segundo identificador de usuario del evento.El segundo
eventtiene un valor que no está codificado en formato hexadecimal en el tercer identificador de usuario del 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
Verifica la carga útil de RequestInfo cada vez que falle una solicitud. Un RequestInfo
contiene el request_id que identifica de forma única tu solicitud a la API.
{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "t-4490c640-dc5d-4c28-91c1-04a1cae0f49f"
}
Cuando registres errores o te comuniques con el equipo de asistencia, asegúrate de incluir el ID de la solicitud para ayudar a diagnosticar los problemas.
ErrorInfo
Verifica el mensaje ErrorInfo para recuperar información adicional que
tal vez no se capture en las otras cargas útiles de detalles estándar. La carga útil de ErrorInfo
contiene un mapa de metadata con información sobre el error.
Por ejemplo, aquí se muestra el ErrorInfo de una falla de PERMISSION_DENIED causada por
el uso de credenciales para un proyecto de Google Cloud en el que
no está habilitada la API de Data Manager. El ErrorInfo proporciona información adicional
sobre el error, como la siguiente:
- Es el proyecto asociado con la solicitud, en
metadata.consumer. - El nombre del servicio, en
metadata.serviceTitle. - Es la URL en la que se puede habilitar el servicio, en
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"
}
},
...
]
}
}
Errores de cuota y límite de frecuencia
Cuando una solicitud supera un límite del proyecto, la API devuelve un error RESOURCE_EXHAUSTED (código de estado HTTP 429). La carga útil ErrorInfo proporciona detalles sobre
qué límite se superó en su mapa metadata:
consumer- Es el proyecto de Google Cloud asociado a la solicitud,
con el formato
projects/PROJECT_NUMBER. quota_limit- Es el nombre del límite de cuota que se excedió, como
IngestionMutateRequestsPerMinutePerProjectoIngestionMutateRequestsPerDayPerProject. Puedes usar este valor para determinar si la aplicación superó un límite por minuto o un límite diario. Para obtener la lista completa de los nombres de los límites, consulta Límites del proyecto. quota_location- Es la ubicación en la que se aplica la cuota. Para la API de Data Manager, siempre es
global. quota_metric- Es la métrica asociada con el límite, como
datamanager.googleapis.com/ingestion_mutate_requests. service- El nombre del servicio,
datamanager.googleapis.com.
Este es un ejemplo de una respuesta de error RESOURCE_EXHAUSTED cuando una solicitud
supera el límite por minuto de solicitudes de mutación de transferencia:
{
"error": {
"code": 429,
"message": "Quota exceeded for quota metric 'Ingestion mutate requests' and limit 'Ingestion mutate requests per minute' of service 'datamanager.googleapis.com' for consumer 'project_number:PROJECT_NUMBER'.",
"status": "RESOURCE_EXHAUSTED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "RATE_LIMIT_EXCEEDED",
"domain": "googleapis.com",
"metadata": {
"consumer": "projects/PROJECT_NUMBER",
"quota_limit": "IngestionMutateRequestsPerMinutePerProject",
"quota_location": "global",
"quota_metric": "datamanager.googleapis.com/ingestion_mutate_requests",
"service": "datamanager.googleapis.com"
}
}
]
}
}
Help y LocalizedMessage
Verifica las cargas útiles Help y LocalizedMessage para obtener vínculos a la documentación y los mensajes de error localizados que te ayuden a comprender y corregir el error.
Por ejemplo, aquí se muestran el Help y el LocalizedMessage de un error PERMISSION_DENIED
causado por el uso de credenciales para un proyecto de Google Cloud
en el que la API de Data Manager no está habilitada. La carga útil de Help muestra la URL en la que se puede habilitar el servicio, y LocalizedMessage tiene una descripción del error.
{
"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"
}
]
},
...
]
}
}
Detalles del error de acceso
Si usas una de las bibliotecas cliente, utiliza los métodos auxiliares para obtener las cargas útiles de detalles estándar.
.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...
// If handling a rate limit error, check the exceeded quota limit:
if (errorInfo.Reason == "RATE_LIMIT_EXCEEDED" &&
errorInfo.Metadata.TryGetValue("quota_limit", out string quotaLimit))
{
// Inspect quotaLimit to determine whether it is a per-minute
// or daily limit (for example,
// IngestionMutateRequestsPerMinutePerProject).
}
// 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'...
// If handling a rate limit error, check the exceeded quota limit:
if (errorInfo != null && "RATE_LIMIT_EXCEEDED".equals(errorInfo.getReason())) {
String quotaLimit = errorInfo.getMetadataMap().get("quota_limit");
// Inspect quotaLimit to determine whether it is a per-minute
// or daily limit (for example,
// IngestionMutateRequestsPerMinutePerProject).
}
// 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 = apiException.getErrorDetails().getRequestInfo();
if (requestInfo != null) {
String requestId = requestInfo.getRequestId();
// Log the requestId...
}
...
}
Controla los errores de tamaño de encabezado para gRPC
Cuando una gran cantidad de registros en una solicitud de transferencia o eliminación no pasa la validación, la API de Data Manager devuelve todos los errores en la carga útil BadRequest de la respuesta.
En gRPC, el servicio devuelve estos detalles del error en los encabezados de respuesta HTTP/2 (metadatos). De forma predeterminada, las bibliotecas cliente de gRPC limitan los encabezados entrantes a un tamaño máximo (por lo general, de 8 a 10 KB). Si los detalles del error superan este límite, el transporte HTTP/2 del cliente falla antes de analizar la respuesta de error y arroja una excepción como la siguiente:
Http2Exception: Header size exceeded max allowed size (10240)
Debido a que el cliente no puede procesar los encabezados de respuesta, cancela la transmisión
(que aparece como estado HTTP 499 Client Closed Request en los registros del servidor)
y tu aplicación no puede acceder a los detalles del error
BadRequest.
Para resolver este problema y, también, inspeccionar la lista completa de errores, configura tu cliente de gRPC con un tamaño máximo de metadatos entrantes mayor (como 16 MB):
.NET
// Creates a client for the ingestion service. Increases the maximum metadata size to // 16MB to prevent RESOURCE_EXHAUSTED errors when responses contain large error // details. IngestionServiceClient ingestionServiceClient = new IngestionServiceClientBuilder { GrpcChannelOptions = GrpcChannelOptions.Empty.WithCustomOption( "grpc.max_metadata_size", 16 * 1024 * 1024 ), }.Build();
Java
// Creates a client for the ingestion service. Increases the maximum metadata size to 16MB to // prevent RESOURCE_EXHAUSTED errors when responses contain large error details. InstantiatingGrpcChannelProvider provider = IngestionServiceSettings.defaultGrpcTransportProviderBuilder() .setMaxInboundMetadataSize(16 * 1024 * 1024) .build(); IngestionServiceSettings settings = IngestionServiceSettings.newBuilder().setTransportChannelProvider(provider).build(); try (IngestionServiceClient ingestionServiceClient = IngestionServiceClient.create(settings)) { // ... }
Nodo
// Creates a client for the ingestion service. Increases the maximum metadata // size to 16MB to prevent RESOURCE_EXHAUSTED errors when responses contain // large error details. const client = new IngestionServiceClient({ 'grpc.max_metadata_size': 16 * 1024 * 1024, });
PHP
// Creates a client for the ingestion service. Increases the maximum metadata size to 16MB to // prevent RESOURCE_EXHAUSTED errors when responses contain large error details. $client = new IngestionServiceClient([ 'transportConfig' => [ 'grpc' => [ 'stubOpts' => [ 'grpc.max_metadata_size' => 16 * 1024 * 1024, ], ], ], ]);
Python
# Creates a client for the ingestion service. Increases the maximum # metadata size to 16MB to prevent RESOURCE_EXHAUSTED errors when responses # contain large error details. channel = datamanager_v1.services.ingestion_service.transports.IngestionServiceGrpcTransport.create_channel( options=[("grpc.max_metadata_size", 16 * 1024 * 1024)] ) transport = datamanager_v1.services.ingestion_service.transports.IngestionServiceGrpcTransport( channel=channel ) client: datamanager_v1.IngestionServiceClient = ( datamanager_v1.IngestionServiceClient(transport=transport) )
Prácticas recomendadas para el manejo de errores
Para compilar aplicaciones resilientes, implementa las siguientes prácticas recomendadas.
- Valida antes de enviar
- Cuando crees o cambies una integración, envía solicitudes con
validateOnlyestablecido entruepara detectar errores de falla rápida antes de transferir datos. - Inspecciona los detalles del error
- Siempre busca una de las cargas útiles de detalles estándar, como
BadRequest. Cada carga útil de detalles estándar contiene información que te ayuda a comprender la causa del error. - Diferencia los errores del cliente de los errores de servidor
Determina si el error se debe a un problema con tu implementación (el cliente) o con la API (el servidor).
- Errores del cliente: Códigos como
INVALID_ARGUMENT,NOT_FOUND,PERMISSION_DENIED,FAILED_PRECONDITION,UNAUTHENTICATED. Estos requieren cambios en la solicitud o en el estado o las credenciales de tu aplicación. No vuelvas a intentar la solicitud sin abordar el problema. - Errores de servidor: Códigos como
UNAVAILABLE,INTERNAL,DEADLINE_EXCEEDED,UNKNOWN. Esto sugiere un problema temporal con el servicio de la API.
- Errores del cliente: Códigos como
- Implementa una estrategia de reintento
Determina si se puede reintentar el error y usa una estrategia de reintento.
Vuelve a intentarlo solo para errores de servidor transitorios (como
UNAVAILABLE,DEADLINE_EXCEEDED,INTERNAL,UNKNOWNyABORTED) y límites de frecuencia por minuto (RESOURCE_EXHAUSTEDconRATE_LIMIT_EXCEEDED).Para conocer los límites de frecuencia, inspecciona el
quota_limitenErrorInfo:Si el límite es por minuto (como
IngestionMutateRequestsPerMinutePerProject), pausa las solicitudes y vuelve a intentarlo con una retirada exponencial con Jitter.Si el límite es diario (como
IngestionMutateRequestsPerDayPerProject), no vuelvas a intentarlo de inmediato. Pausar el procesamiento hasta que se restablezca la cuota diaria a la medianoche, hora del Pacífico.
Usa un algoritmo de retirada exponencial para esperar períodos cada vez más largos entre los reintentos. Esto ayuda a evitar que se sobrecargue un servicio que ya está saturado. Por ejemplo, espera 1 s, luego 2 s, luego 4 s, y continúa hasta alcanzar una cantidad máxima de reintentos o un tiempo de espera total.
Agrega una pequeña cantidad aleatoria de "fluctuación" a los retrasos de retirada para evitar el problema de "activación simultánea" en el que muchos clientes vuelven a intentarlo simultáneamente.
- Registra con detalle
Registra la respuesta de error completa, incluidas todas las cargas útiles de detalles estándar, en especial el ID de solicitud. Esta información es esencial para depurar y, si es necesario, informar problemas al equipo de Atención al cliente de Google.
- Proporciona comentarios de los usuarios
Según los códigos y los mensajes de las cargas útiles de detalles estándar, proporciona comentarios claros y útiles a los usuarios de tu aplicación. Por ejemplo, en lugar de solo "Se produjo un error", puedes decir "Falta el ID de transacción" o "No se encontró el ID de cuenta del destino".
Si sigues estos lineamientos, podrás diagnosticar y controlar de manera eficaz los errores que devuelve la API de Data Manager, lo que generará aplicaciones más estables y fáciles de usar.