Entender os erros da API

Este guia explica como a API Data Manager processa e comunica erros. Entender a estrutura e o significado dos erros de API é crucial para criar aplicativos robustos que possam lidar com problemas, desde entradas inválidas até indisponibilidade temporária de serviço.

A API Data Manager segue o modelo de erro padrão da API do Google, que é baseado nos códigos de status do gRPC. Cada resposta da API que resulta em um erro inclui um objeto Status com:

  • Um código do erro numérico.
  • Uma mensagem de erro.
  • Detalhes adicionais opcionais do erro.

Códigos de erro canônicos

A API Data Manager usa um conjunto de códigos do erro canônicos definidos por gRPC e HTTP. Esses códigos fornecem uma indicação de alto nível do tipo de erro. Sempre verifique esse código primeiro para entender a natureza fundamental do problema.

Para mais detalhes sobre esses códigos, consulte o Guia de design de API: códigos do erro.

Modelo de falha rápida

A API Data Manager usa um modelo de falha rápida. Se uma solicitação tiver erros estruturais ou se algum registro falhar na validação de um campo obrigatório, toda a solicitação vai falhar, e a API não vai processar nenhum dos dados nela.

Comparação com o modelo de falha parcial

O modelo de falha rápida é diferente do modelo de falha parcial em algumas outras APIs do Google, como a API Google Ads e a API Campaign Manager 360. No modelo de falha parcial, uma solicitação é bem-sucedida mesmo que alguns registros tenham erros, e a resposta contém detalhes de erro para os registros com falha.

Embora a falha parcial possa ser conveniente, ela apresenta riscos significativos porque o modelo de falha parcial não alerta você proativamente sobre erros. É necessário verificar explicitamente se há erros em cada resposta. Isso pode mascarar problemas importantes, porque uma solicitação é bem-sucedida mesmo que a API rejeite muitos ou até mesmo todos os registros na solicitação. Se uma parte significativa dos registros em uma solicitação tiver erros, mas você não inspecionar a resposta, talvez não perceba problemas generalizados com seus dados e só os descubra dias ou semanas depois, quando os resultados cumulativos não estiverem de acordo com suas expectativas.

O modelo de falha rápida evita essas armadilhas alertando você sobre problemas com seus dados ou integração imediatamente para que você possa tomar as medidas apropriadas.

Verificar se há erros de falha rápida com validateOnly

A maioria das solicitações de ingestão e remoção aceita um campo validateOnly. Quando você define validateOnly como true, a API Data Manager executa as mesmas verificações de validação básicas de uma solicitação normal, mas não ingere nem remove dados.

  • Se a solicitação tiver erros, ela vai falhar com a mesma resposta de erro que você receberia de uma solicitação normal.
  • Se a solicitação for aprovada na validação, ela será bem-sucedida. A resposta inclui qualquer fieldWarnings para campos opcionais, assim como uma solicitação normal.

Use o validateOnly para:

  • Teste uma integração nova ou atualizada sem afetar seus dados em tempo real.
  • Confirme se uma correção resolve um erro antes de reenviar a solicitação.

Solucionar erros

Siga estas etapas quando uma solicitação falhar:

  1. Verifique o código do erro para encontrar o tipo de erro.

    • Se você usa o gRPC, o código do erro está no campo code do Status. Se você usar uma biblioteca de cliente, ela poderá gerar um tipo específico de exceção que corresponde ao código do erro. Por exemplo, a biblioteca de cliente para Java gera uma com.google.api.gax.rpc.InvalidArgumentException se o código do erro for INVALID_ARGUMENT.
    • Se você usa REST, o código do erro está na resposta de erro em error.status, e o status HTTP correspondente está em error.code.
  2. Verifique o payload de detalhes padrão para o código do erro. Os payloads de detalhes padrão são um conjunto de mensagens para erros das APIs do Google. Eles fornecem detalhes de erros de maneira estruturada e consistente. Cada erro da API Data Manager pode ter várias mensagens de payload de detalhes padrão. As bibliotecas de cliente da API Data Manager têm métodos auxiliares para receber os payloads de detalhes padrão de um erro.

    Seja qual for o código do erro, recomendamos que você verifique e registre os payloads ErrorInfo, RequestInfo, Help e LocalizedMessage.

    • ErrorInfo tem informações que podem não estar em outros payloads.
    • RequestInfo tem o ID da solicitação, que é útil se você precisar entrar em contato com o suporte.
    • Help e LocalizedMessage contêm links e outros detalhes para ajudar você a resolver o erro.

    Além disso, o payload BadRequest é útil para erros INVALID_ARGUMENT, porque fornece informações sobre quais campos causaram o erro.

Avisos de ingestão

A API Data Manager aceita o máximo possível de uma solicitação de ingestão. Se você incluir dados que não são obrigatórios, as falhas de validação nesses campos não vão causar falhas na solicitação. Por exemplo, se um item do carrinho não tiver um ID do produto do comerciante, a API vai processar o restante da solicitação e retornar um aviso.

Uma resposta de ingestão bem-sucedida (código de status HTTP 200) inclui esses avisos em uma lista fieldWarnings. Cada entrada é um objeto FieldWarning com os seguintes campos:

field

O local do campo na solicitação, na sintaxe do caminho snake_case.

Se um caminho apontar para um item em uma lista (um campo repeated), o índice dele será mostrado entre colchetes ([...]) após o nome da lista.

Por exemplo, events.events[0].cart_data.items[0].merchant_product_id identifica um aviso relacionado ao primeiro item nos dados do carrinho do primeiro evento na solicitação.

description

Uma explicação do motivo pelo qual o valor fornecido causou um aviso.

reason

O valor de tipo enumerado WarningReason que identifica o tipo de aviso.

Exemplo com FieldWarning

Veja um exemplo de resposta para uma solicitação de ingestão bem-sucedida que contém um aviso porque um ID do produto do comerciante estava ausente em um dos itens do carrinho.

{
  "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"
    }
  ]
}

Payloads de detalhes padrão

Os payloads de detalhes padrão mais comuns para a API Data Manager são:

BadRequest

Verifique o payload BadRequest quando uma solicitação falhar com INVALID_ARGUMENT (código de status HTTP 400).

Uma mensagem BadRequest mostra que a solicitação tinha campos com valores incorretos ou que faltava um valor para um campo obrigatório. Verifique a lista field_violations no BadRequest para descobrir quais campos têm erros. Cada entrada field_violations tem informações para ajudar você a corrigir o erro:

field

O local do campo na solicitação, na sintaxe do caminho snake_case.

Se um caminho apontar para um item em uma lista (um campo repeated), o índice dele será mostrado entre colchetes ([...]) após o nome da lista.

Por exemplo, destinations[0].operating_account.account_id é o account_id no operating_account do primeiro item na lista destinations.

description

Uma explicação do motivo pelo qual o valor causou um erro.

reason

O tipo enumerado ErrorReason, como INVALID_HEX_ENCODING ou INVALID_CURRENCY_CODE.

Exemplos de BadRequest

Veja um exemplo de resposta para um erro INVALID_ARGUMENT com uma mensagem BadRequest. O field_violations mostra que o erro é um accountId que não é um número. O valor destinations[0].login_account.account_id de field mostra que o accountId com uma violação de campo está no login_account do primeiro item na 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"
          }
        ]
      }
    ]
  }
}

Veja outro exemplo de resposta de um erro INVALID_ARGUMENT com uma mensagem BadRequest. Nesse caso, a lista field_violations mostra dois erros:

  1. O primeiro event tem um valor que não é codificado em hexadecimal no segundo identificador de usuário do evento.

  2. O segundo event tem um valor que não é codificado em hexadecimal no terceiro identificador de usuário do 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

Verifique o payload RequestInfo sempre que uma solicitação falhar. Um RequestInfo contém o request_id que identifica exclusivamente sua solicitação de API.

{
  "@type": "type.googleapis.com/google.rpc.RequestInfo",
  "requestId": "t-4490c640-dc5d-4c28-91c1-04a1cae0f49f"
}

Ao registrar erros ou entrar em contato com o suporte, inclua o ID da solicitação para ajudar no diagnóstico de problemas.

ErrorInfo

Verifique a mensagem ErrorInfo para recuperar outras informações que podem não ser capturadas nos outros payloads de detalhes padrão. O payload ErrorInfo contém um mapa metadata com informações sobre o erro.

Por exemplo, veja o ErrorInfo de uma falha de PERMISSION_DENIED causada pelo uso de credenciais de um projeto na nuvem do Google Cloud em que a API Data Manager não está ativada. O ErrorInfo fornece mais informações sobre o erro, como:

  • O projeto associado à solicitação, em metadata.consumer.
  • O nome do serviço, em metadata.serviceTitle.
  • O URL em que o serviço pode ser ativado, em 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"
        }
      },
      ...
    ]
  }
}

Erros de limite de taxa e cota

Quando uma solicitação excede um limite do projeto, a API retorna um erro RESOURCE_EXHAUSTED (código de status HTTP 429). O payload ErrorInfo fornece detalhes sobre qual limite foi excedido no mapa metadata:

consumer
O projeto na nuvem do Google Cloud associado à solicitação, formatado como projects/PROJECT_NUMBER.
quota_limit
O nome do limite de cota que foi excedido, como IngestionMutateRequestsPerMinutePerProject ou IngestionMutateRequestsPerDayPerProject. Use esse valor para determinar se o aplicativo excedeu um limite por minuto ou limite diário. Para ver a lista completa de nomes de limites, consulte Limites do projeto.
quota_location
O local em que a cota é aplicada. Para a API Data Manager, é sempre global.
quota_metric
A métrica associada ao limite, como datamanager.googleapis.com/ingestion_mutate_requests.
service
O nome do serviço, datamanager.googleapis.com.

Veja um exemplo de resposta de erro RESOURCE_EXHAUSTED quando uma solicitação excede o limite por minuto para solicitações de mutação de ingestão:

{
  "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 e LocalizedMessage

Verifique os payloads Help e LocalizedMessage para acessar links para a documentação e mensagens de erro localizadas que ajudam a entender e corrigir o erro.

Por exemplo, aqui estão os valores de Help e LocalizedMessage para uma falha de PERMISSION_DENIED causada pelo uso de credenciais de um projeto na nuvem do Google Cloud em que a API Data Manager não está ativada. O payload Help mostra o URL em que o serviço pode ser ativado, e o LocalizedMessage tem uma descrição do erro.

{
  "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"
          }
        ]
      },
      ...
    ]
  }
}

Detalhes do erro de acesso

Se você estiver usando uma das bibliotecas de cliente, use os métodos auxiliares para receber os payloads de detalhes padrão.

.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...
  }
  ...
}

Tratar erros de tamanho de cabeçalho para gRPC

Quando um grande número de registros em uma solicitação de ingestão ou pedido de remoção falha na validação, a API Data Manager retorna todos os erros no payload BadRequest da resposta.

No gRPC, o serviço retorna esses detalhes de erro nos cabeçalhos de resposta HTTP/2 (metadados). Por padrão, as bibliotecas de cliente do gRPC limitam os cabeçalhos de entrada a um tamanho máximo (normalmente de 8 a 10 KB). Se os detalhes do erro excederem esse limite, o transporte HTTP/2 do lado do cliente falhará antes de analisar a resposta de erro, gerando uma exceção como:

Http2Exception: Header size exceeded max allowed size (10240)

Como o cliente não pode processar os cabeçalhos de resposta, ele cancela o stream (que aparece como status HTTP 499 Client Closed Request nos registros do lado do servidor), e o aplicativo não pode acessar os detalhes do erro BadRequest.

Para resolver esse problema e inspecionar a lista completa de erros, configure o cliente gRPC com um tamanho máximo de metadados de entrada maior (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)) {
  // ...
}

Nó

// 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áticas recomendadas para tratamento de erros

Para criar aplicativos resilientes, implemente as práticas recomendadas a seguir.

Validar antes de enviar
Ao criar ou mudar uma integração, envie solicitações com validateOnly definido como true para capturar erros de falha rápida antes de ingerir dados.
Inspecionar detalhes do erro
Sempre procure um dos payloads de detalhes padrão, como BadRequest. Cada payload de detalhes padrão contém informações para ajudar você a entender a causa do erro.
Diferenciar erros do cliente e erros de servidor

Determine se o erro é causado por um problema na sua implementação (o cliente) ou na API (o servidor).

  • Erros do cliente: códigos como INVALID_ARGUMENT, NOT_FOUND, PERMISSION_DENIED, FAILED_PRECONDITION, UNAUTHENTICATED. Elas exigem mudanças na solicitação ou no estado/nas credenciais do aplicativo. Não tente fazer a solicitação novamente sem resolver o problema.
  • Erros de servidor: códigos como UNAVAILABLE, INTERNAL, DEADLINE_EXCEEDED, UNKNOWN. Isso sugere um problema temporário com o serviço da API.
Implementar uma estratégia de novas tentativas

Determine se o erro pode ser repetido e use uma estratégia de repetição.

  • Tente novamente apenas para erros de servidor temporários (como UNAVAILABLE, DEADLINE_EXCEEDED, INTERNAL, UNKNOWN e ABORTED) e limites de taxa por minuto (RESOURCE_EXHAUSTED com RATE_LIMIT_EXCEEDED).

  • Para limites de taxa, inspecione o quota_limit em ErrorInfo:

    • Se o limite for por minuto (como IngestionMutateRequestsPerMinutePerProject), pause as solicitações e tente novamente usando a espera exponencial com instabilidade.

    • Se o limite for diário (como IngestionMutateRequestsPerDayPerProject), não tente novamente imediatamente. Pause o processamento até que a cota diária seja redefinida à meia-noite, horário do Pacífico.

  • Use um algoritmo de espera exponencial para aguardar períodos crescentes entre as novas tentativas. Isso ajuda a evitar sobrecarregar um serviço que já está estressado. Por exemplo, aguarde 1s, depois 2s, depois 4s, continuando até um número máximo de novas tentativas ou tempo de espera total.

  • Adicione uma pequena quantidade aleatória de "jitter" aos atrasos de espera para evitar o problema de "rebanho estrondoso", em que muitos clientes tentam novamente ao mesmo tempo.

Registrar tudo

Registre a resposta de erro completa, incluindo todos os payloads de detalhes padrão, especialmente o ID da solicitação. Essas informações são essenciais para depurar e informar problemas ao Suporte do Google, se necessário.

Enviar feedback do usuário

Com base nos códigos e nas mensagens nos payloads de detalhes padrão, forneça feedback claro e útil aos usuários do aplicativo. Por exemplo, em vez de apenas "Ocorreu um erro", você pode dizer "O ID da transação estava ausente" ou "O ID da conta de destino não foi encontrado".

Ao seguir essas diretrizes, você pode diagnosticar e processar com eficácia os erros retornados pela API Data Manager, o que resulta em aplicativos mais estáveis e fáceis de usar.