Ce guide explique comment l'API Data Manager gère et communique les erreurs. Il est essentiel de comprendre la structure et la signification des erreurs d'API pour créer des applications robustes capables de gérer correctement les problèmes, qu'il s'agisse d'une entrée non valide ou d'une indisponibilité temporaire du service.
L'API Data Manager suit le modèle d'erreur standard des API Google, qui est basé sur les codes d'état gRPC. Chaque réponse de l'API qui entraîne une erreur inclut un objet Status avec :
- Code d'erreur numérique.
- Message d'erreur.
- Informations supplémentaires facultatives sur l'erreur.
Codes d'erreur canoniques
L'API Data Manager utilise un ensemble de codes d'erreur canoniques définis par gRPC et HTTP. Ces codes fournissent une indication générale du type d'erreur. Vous devez toujours vérifier ce code en premier pour comprendre la nature fondamentale du problème.
Pour en savoir plus sur ces codes, consultez Guide de conception d'API : codes d'erreur.
Modèle d'échec rapide
L'API Data Manager utilise un modèle d'échec rapide. Si une requête contient des erreurs structurelles ou si un enregistrement ne passe pas la validation d'un champ obligatoire, l'ensemble de la requête échoue et l'API ne traite aucune des données de cette requête.
Comparaison avec le modèle d'échec partiel
Le modèle d'échec rapide diffère du modèle d'échec partiel de certaines autres API Google, telles que l'API Google Ads et l'API Campaign Manager 360. Dans le modèle d'échec partiel, une requête aboutit même si certains enregistrements comportent des erreurs, et la réponse contient des détails sur les erreurs pour les enregistrements ayant échoué.
Bien qu'un échec partiel puisse être pratique, il comporte des risques importants, car le modèle d'échec partiel ne vous alerte pas de manière proactive en cas d'erreur. Vous devez rechercher explicitement les erreurs dans chaque réponse. Cela peut masquer des problèmes importants, car une requête réussit même si l'API rejette un grand nombre d'enregistrements, voire tous les enregistrements de la requête. Si une partie importante des enregistrements d'une requête comporte des erreurs, mais que vous n'inspectez pas la réponse, vous risquez de ne pas être au courant des problèmes généralisés liés à vos données et de ne les découvrir que quelques jours ou semaines plus tard, lorsque les résultats cumulés ne correspondent pas à vos attentes.
Le modèle d'échec rapide évite ces écueils en vous alertant immédiatement des problèmes liés à vos données ou à l'intégration, afin que vous puissiez prendre les mesures appropriées.
Rechercher les erreurs d'échec rapide avec validateOnly
La plupart des requêtes d'ingestion et des demandes de suppression acceptent un champ validateOnly. Lorsque vous définissez validateOnly sur true, l'API Data Manager exécute les mêmes vérifications de validation de base que pour une requête standard, mais n'ingère ni ne supprime aucune donnée.
- Si la requête comporte des erreurs, elle échoue avec la même réponse d'erreur que celle que vous obtiendriez avec une requête standard.
- Si la requête est validée, elle aboutit. La réponse inclut toutes les
fieldWarningspour les champs facultatifs, comme une requête standard.
Utiliser validateOnly pour :
- Testez une intégration nouvelle ou mise à jour sans affecter vos données de production.
- Vérifiez qu'un correctif résout une erreur avant de renvoyer la requête.
Gérer les erreurs
Suivez ces étapes en cas d'échec d'une requête :
Vérifiez le code d'erreur pour identifier le type d'erreur.
- Si vous utilisez gRPC, le code d'erreur se trouve dans le champ
codedeStatus. Si vous utilisez une bibliothèque cliente, elle peut générer un type d'exception spécifique correspondant au code d'erreur. Par exemple, la bibliothèque cliente pour Java génère une exceptioncom.google.api.gax.rpc.InvalidArgumentExceptionsi le code d'erreur estINVALID_ARGUMENT. - Si vous utilisez REST, le code d'erreur se trouve dans la réponse d'erreur à l'emplacement
error.status, et l'état HTTP correspondant se trouve à l'emplacementerror.code.
- Si vous utilisez gRPC, le code d'erreur se trouve dans le champ
Recherchez la charge utile de détail standard pour le code d'erreur. Les charges utiles de détails standards sont un ensemble de messages pour les erreurs des API Google. Ils vous fournissent des détails sur les erreurs de manière structurée et cohérente. Chaque erreur de l'API Data Manager peut comporter plusieurs messages de charge utile standards. Les bibliothèques clientes de l'API Data Manager disposent de méthodes d'assistance pour obtenir les charges utiles de détails standards à partir d'une erreur.
Quel que soit le code d'erreur, nous vous recommandons de vérifier et de consigner les charges utiles
ErrorInfo,RequestInfo,HelpetLocalizedMessage.ErrorInfocontient des informations qui ne figurent peut-être pas dans d'autres charges utiles.RequestInfocontient l'ID de la demande, ce qui est utile si vous devez contacter l'assistance.HelpetLocalizedMessagecontiennent des liens et d'autres informations pour vous aider à résoudre l'erreur.
De plus, la charge utile
BadRequestest utile pour les erreursINVALID_ARGUMENT, car elle fournit des informations sur les champs à l'origine de l'erreur.
Avertissements d'ingestion
L'API Data Manager accepte autant de requêtes d'ingestion que possible. Si vous incluez des données qui ne sont pas obligatoires, les échecs de validation de ces champs n'entraîneront pas l'échec de la requête. Par exemple, s'il manque un ID produit du marchand pour un article du panier, l'API traite le reste de la requête et renvoie un avertissement.
Une réponse d'ingestion réussie (code d'état HTTP 200) inclut ces avertissements dans une liste fieldWarnings. Chaque entrée est un objet FieldWarning comportant les champs suivants :
fieldEmplacement du champ dans la requête, dans la syntaxe du chemin d'accès snake_case.
Si un chemin d'accès pointe vers un élément d'une liste (un champ
repeated), son index est affiché entre crochets ([...]) après le nom de la liste.Par exemple,
events.events[0].cart_data.items[0].merchant_product_ididentifie un avertissement lié au premier article des données du panier du premier événement de la requête.descriptionExplication de la raison pour laquelle la valeur fournie a généré un avertissement.
reasonValeur d'énumération
WarningReasonqui identifie le type d'avertissement.
Exemple avec FieldWarning
Voici un exemple de réponse pour une requête d'ingestion réussie qui contient un avertissement, car l'ID produit du marchand était manquant pour l'un des articles du panier.
{
"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"
}
]
}
Charges utiles de détails standards
Voici les charges utiles de détails standards les plus courantes pour l'API Data Manager :
BadRequest
Recherchez la charge utile BadRequest lorsqu'une requête échoue avec INVALID_ARGUMENT (code d'état HTTP 400).
Un message BadRequest indique que la requête comportait des champs avec des valeurs incorrectes ou qu'il manquait une valeur pour un champ obligatoire. Consultez la liste field_violations dans BadRequest pour identifier les champs qui comportent des erreurs. Chaque entrée field_violations contient des informations pour vous aider à corriger l'erreur :
fieldEmplacement du champ dans la requête, dans la syntaxe du chemin d'accès snake_case.
Si un chemin d'accès pointe vers un élément d'une liste (un champ
repeated), son index est affiché entre crochets ([...]) après le nom de la liste.Par exemple,
destinations[0].operating_account.account_idest laaccount_iddans laoperating_accountdu premier élément de la listedestinations.descriptionExplication de la raison pour laquelle la valeur a provoqué une erreur.
reasonL'énumération
ErrorReason, telle queINVALID_HEX_ENCODINGouINVALID_CURRENCY_CODE.
Exemples de BadRequest
Voici un exemple de réponse pour une erreur INVALID_ARGUMENT avec un message BadRequest. field_violations indique que l'erreur est un accountId qui n'est pas un nombre. La valeur destinations[0].login_account.account_id de field indique que l'accountId présentant une violation de champ se trouve dans le login_account du premier élément de la liste 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"
}
]
}
]
}
}
Voici un autre exemple de réponse d'une erreur INVALID_ARGUMENT avec un message BadRequest. Dans ce cas, la liste field_violations affiche deux erreurs :
Le premier
eventcomporte une valeur qui n'est pas encodée au format hexadécimal sur le deuxième identifiant utilisateur de l'événement.Le deuxième
eventa une valeur qui n'est pas encodée au format hexadécimal sur le troisième identifiant utilisateur de l'événement.
{
"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
Recherchez la charge utile RequestInfo chaque fois qu'une requête échoue. Un RequestInfo contient l'request_id qui identifie de manière unique votre requête API.
{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "t-4490c640-dc5d-4c28-91c1-04a1cae0f49f"
}
Lorsque vous consignez des erreurs ou que vous contactez l'assistance, veillez à inclure l'ID de requête pour faciliter le diagnostic des problèmes.
ErrorInfo
Recherchez le message ErrorInfo pour récupérer des informations supplémentaires qui ne sont peut-être pas capturées dans les autres charges utiles de détails standards. La charge utile ErrorInfo contient un mappage metadata avec des informations sur l'erreur.
Par exemple, voici le ErrorInfo d'un échec de PERMISSION_DENIED causé par l'utilisation d'identifiants pour un projet Google Cloud dans lequel l'API Data Manager n'est pas activée. ErrorInfo fournit des informations supplémentaires sur l'erreur, par exemple :
- Projet associé à la requête, sous
metadata.consumer. - Le nom du service, sous
metadata.serviceTitle. - URL où le service peut être activé, sous
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"
}
},
...
]
}
}
Erreurs de quota et de limite de débit
Lorsqu'une requête dépasse une limite de projet, l'API renvoie une erreur RESOURCE_EXHAUSTED (code d'état HTTP 429). La charge utile ErrorInfo fournit des détails sur la limite dépassée dans son mappage metadata :
consumer- Projet Google Cloud associé à la requête, au format
projects/PROJECT_NUMBER. quota_limit- Nom de la limite de quota dépassée, par exemple
IngestionMutateRequestsPerMinutePerProjectouIngestionMutateRequestsPerDayPerProject. Vous pouvez utiliser cette valeur pour déterminer si l'application a dépassé une limite par minute ou une limite quotidienne. Pour obtenir la liste complète des noms de limites, consultez Limites du projet. quota_location- Emplacement où le quota est appliqué. Pour l'API Data Manager, il s'agit toujours de
global. quota_metric- Métrique associée à la limite, telle que
datamanager.googleapis.com/ingestion_mutate_requests. service- Le nom du service,
datamanager.googleapis.com.
Voici un exemple de réponse d'erreur RESOURCE_EXHAUSTED lorsqu'une requête dépasse la limite par minute pour les requêtes de modification d'ingestion :
{
"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 et LocalizedMessage
Recherchez les charges utiles Help et LocalizedMessage pour obtenir des liens vers la documentation et les messages d'erreur localisés qui vous aideront à comprendre et à corriger l'erreur.
Par exemple, voici les valeurs Help et LocalizedMessage pour un échec PERMISSION_DENIED causé par l'utilisation d'identifiants pour un projet Google Cloud dans lequel l'API Data Manager n'est pas activée. La charge utile Help affiche l'URL où le service peut être activé, et LocalizedMessage contient une description de l'erreur.
{
"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"
}
]
},
...
]
}
}
Détails de l'erreur d'accès
Si vous utilisez l'une des bibliothèques clientes, utilisez les méthodes d'assistance pour obtenir les charges utiles de détails standards.
.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...
}
...
}
Gérer les erreurs de taille d'en-tête pour gRPC
Lorsqu'un grand nombre d'enregistrements d'une requête d'ingestion ou de demande de suppression échouent à la validation, l'API Data Manager renvoie toutes les erreurs dans la charge utile BadRequest de la réponse.
Dans gRPC, le service renvoie ces détails d'erreur dans les en-têtes de réponse HTTP/2 (métadonnées). Par défaut, les bibliothèques clientes gRPC limitent la taille maximale des en-têtes entrants (généralement de 8 à 10 Ko). Si les détails de l'erreur dépassent cette limite, le transport HTTP/2 côté client échoue avant l'analyse de la réponse d'erreur, ce qui génère une exception telle que :
Http2Exception: Header size exceeded max allowed size (10240)
Comme le client ne peut pas traiter les en-têtes de réponse, il annule le flux (qui apparaît comme l'état HTTP 499 Client Closed Request dans les journaux côté serveur), et votre application ne peut pas accéder aux détails de l'erreur BadRequest.
Pour résoudre ce problème et inspecter la liste complète des erreurs, configurez votre client gRPC avec une taille maximale de métadonnées entrantes plus élevée (par exemple, 16 Mo) :
.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œud
// 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) )
Bonnes pratiques pour la gestion des erreurs
Pour créer des applications résilientes, mettez en œuvre les bonnes pratiques suivantes.
- Valider avant d'envoyer
- Lorsque vous créez ou modifiez une intégration, envoyez des requêtes avec
validateOnlydéfini surtruepour détecter les erreurs d'échec rapide avant d'ingérer des données. - Inspecter les détails de l'erreur
- Recherchez toujours l'une des charges utiles de détails standards, telles que
BadRequest. Chaque charge utile de détail standard contient des informations pour vous aider à comprendre la cause de l'erreur. - Différencier les erreurs client des erreurs serveur
Déterminez si l'erreur est due à un problème lié à votre implémentation (le client) ou à un problème lié à l'API (le serveur).
- Erreurs client : codes tels que
INVALID_ARGUMENT,NOT_FOUND,PERMISSION_DENIED,FAILED_PRECONDITION,UNAUTHENTICATED. Elles nécessitent des modifications de la requête ou de l'état/des identifiants de votre application. Ne relancez pas la requête avant d'avoir résolu le problème. - Erreurs de serveur : codes tels que
UNAVAILABLE,INTERNAL,DEADLINE_EXCEEDED,UNKNOWN. Ces codes indiquent un problème temporaire avec le service d'API.
- Erreurs client : codes tels que
- Mettre en œuvre une stratégie de nouvelle tentative
Déterminez si l'erreur peut être relancée et utilisez une stratégie de nouvelle tentative.
Réessayez uniquement pour les erreurs de serveur temporaires (telles que
UNAVAILABLE,DEADLINE_EXCEEDED,INTERNAL,UNKNOWNetABORTED) et les limites de débit par minute (RESOURCE_EXHAUSTEDavecRATE_LIMIT_EXCEEDED).Pour les limites de débit, inspectez
quota_limitdansErrorInfo:Si la limite est par minute (par exemple,
IngestionMutateRequestsPerMinutePerProject), suspendez les requêtes et réessayez en utilisant un intervalle exponentiel entre les tentatives avec gigue.Si la limite est quotidienne (par exemple,
IngestionMutateRequestsPerDayPerProject), ne réessayez pas immédiatement. Mettez en pause le traitement jusqu'à ce que le quota quotidien soit réinitialisé à minuit (heure du Pacifique).
Utilisez un algorithme d'intervalle exponentiel entre les tentatives pour attendre des périodes de plus en plus longues entre les tentatives. Cela permet d'éviter de surcharger un service déjà saturé. Par exemple, attendez 1 s, puis 2 s, puis 4 s, jusqu'à atteindre un nombre maximal de tentatives ou un temps d'attente total.
Ajoutez une petite quantité aléatoire de "gigue" aux délais d'intervalle exponentiel entre les tentatives pour éviter le problème de "troupeau tonitruant" où de nombreux clients effectuent une nouvelle tentative simultanément.
- Enregistrez tout
Enregistrez la réponse d'erreur complète, y compris toutes les charges utiles de détails standards, en particulier l'ID de requête. Ces informations sont essentielles pour déboguer et signaler des problèmes à l'assistance Google si nécessaire.
- Envoyer des commentaires utilisateur
En fonction des codes et des messages des charges utiles de détails standards, fournissez des commentaires clairs et utiles aux utilisateurs de votre application. Par exemple, au lieu de simplement "Une erreur s'est produite", vous pouvez indiquer "ID de transaction manquant" ou "ID de compte de la destination introuvable".
En suivant ces consignes, vous pouvez diagnostiquer et gérer efficacement les erreurs renvoyées par l'API Data Manager, ce qui vous permet de créer des applications plus stables et plus conviviales.