API エラーについて

このガイドでは、Data Manager API がエラーを処理して通知する方法について説明します。API エラーの構造と意味を理解することは、無効な入力から一時的なサービスの利用不可まで、問題を適切に処理できる堅牢なアプリケーションを構築するうえで重要です。

Data Manager API は、gRPC ステータス コードに基づく標準の Google API エラーモデルに準拠しています。エラーが発生した各 API レスポンスには、次の Status オブジェクトが含まれます。

  • 数値のエラーコード。
  • エラー メッセージ。
  • 省略可。エラーの詳細。

標準的なエラーコード

Data Manager API は、gRPC と HTTP で定義された正規のエラーコードのセットを使用します。これらのコードは、エラーの種類を大まかに示します。問題の根本的な性質を理解するには、まずこのコードを確認する必要があります。

これらのコードの詳細については、API 設計ガイド - エラーコードをご覧ください。

早期失敗モデル

Data Manager API は、高速フェイルモデルを使用します。リクエストに構造エラーが含まれている場合、または必須フィールドの検証に失敗したレコードがある場合、リクエスト全体が失敗し、API はそのリクエストのデータを処理しません。

部分障害モデルとの比較

高速フェイルモデルは、Google Ads API や キャンペーン マネージャー 360 API などの他の Google API の部分障害モデルとは異なります。部分的な失敗モデルでは、一部のレコードにエラーがあってもリクエストは成功し、レスポンスには失敗したレコードのエラーの詳細が含まれます。

部分的な失敗は便利ですが、部分的な失敗モデルではエラーが事前に通知されないため、大きなリスクを伴います。各レスポンスでエラーを明示的に確認する必要があります。API がリクエスト内の多くのレコード(またはすべてのレコード)を拒否してもリクエストが成功するため、重要な問題が隠蔽される可能性があります。リクエスト内のレコードの大部分にエラーがあるにもかかわらず、レスポンスを検査しない場合、データに広範な問題があることにまったく気付かず、数日または数週間後に累積結果が期待どおりにならないときに初めて問題に気付く可能性があります。

高速フェイル モデルでは、データや統合の問題をすぐにアラートで通知することで、これらの問題を回避し、適切な対応を取ることができます。

validateOnly でファストフェイル エラーを確認する

ほとんどの取り込みリクエストと削除リクエストは、validateOnly フィールドをサポートしています。validateOnly を true に設定すると、Data Manager API は通常の要求と同じ基本的な検証チェックを実行しますが、データの取り込みや削除は行いません。

  • リクエストにエラーがある場合は、通常のリクエストから返されるエラー レスポンスと同じエラー レスポンスが返されます。
  • リクエストが検証に合格すると、成功します。レスポンスには、通常のリクエストと同様に、オプション フィールドの fieldWarnings が含まれます。

validateOnly を使用して、次の権限を付与します。

  • ライブデータに影響を与えることなく、新しい統合または更新された統合をテストします。
  • リクエストを再送信する前に、修正によってエラーが解決することを確認します。

エラーを処理する

リクエストが失敗した場合は、次の手順を行います。

  1. エラーコードを確認して、エラーの種類を特定します。

    • gRPC を使用する場合、エラーコードは Status の code フィールドにあります。 クライアント ライブラリを使用している場合は、エラーコードに対応する特定の種類の例外がスローされることがあります。たとえば、Java 用のクライアント ライブラリは、エラーコードが INVALID_ARGUMENT の場合に com.google.api.gax.rpc.InvalidArgumentException をスローします。
    • REST を使用している場合、エラーコードは error.status のエラー レスポンスにあり、対応する HTTP ステータスは error.code にあります。
  2. エラーコードの標準の詳細ペイロードを確認します。標準の詳細ペイロードは、Google API からのエラー メッセージのセットです。エラーの詳細が構造化された一貫性のある方法で提供されます。Data Manager API からのエラーには、複数の標準詳細ペイロード メッセージが含まれる場合があります。Data Manager API クライアント ライブラリには、エラーから標準の詳細ペイロードを取得するヘルパー メソッドがあります。

    エラーコードに関係なく、ErrorInfo、RequestInfo、Help、LocalizedMessage のペイロードを確認してログに記録することをおすすめします。

    • ErrorInfo には、他のペイロードには含まれていない可能性のある情報が含まれています。
    • RequestInfo にはリクエスト ID が含まれています。これは、サポートに問い合わせる必要がある場合に役立ちます。
    • Help と LocalizedMessage には、エラーの解決に役立つリンクなどの詳細情報が含まれています。

    また、BadRequest ペイロードは、エラーの原因となったフィールドに関する情報を提供するため、INVALID_ARGUMENT エラーに役立ちます。

取り込みに関する警告

Data Manager API は、可能な限り多くの取り込みリクエストを受け入れます。必須ではないデータを含めた場合、それらのフィールドの検証に失敗しても、リクエストは失敗しません。たとえば、カートアイテムに販売者の商品 ID がない場合、API はリクエストの残りの部分を処理し、警告を返します。

取り込みが成功したレスポンス(HTTP ステータス コード 200)には、fieldWarnings リストにこれらの警告が含まれます。各エントリは、次のフィールドを含む FieldWarning オブジェクトです。

field

リクエスト内のフィールドの場所(スネークケースのパス構文)。

パスがリスト内のアイテム(repeated フィールド)を指している場合、そのインデックスはリスト名の後に角かっこ([...])で囲まれて表示されます。

たとえば、events.events[0].cart_data.items[0].merchant_product_id は、リクエストの最初のイベントのカートのデータの最初のアイテムに関連する警告を識別します。

description

指定された値が警告の原因となった理由の説明。

reason

警告のタイプを識別する WarningReason 列挙値。

FieldWarning の例

以下は、カートアイテムの 1 つに販売者の商品 ID がなかったため、警告を含む、取り込みリクエストが成功した場合のレスポンスの例です。

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

標準の詳細ペイロード

Data Manager API の最も一般的な標準詳細ペイロードは次のとおりです。

BadRequest

リクエストが INVALID_ARGUMENT(HTTP ステータス コード 400)で失敗した場合は、BadRequest ペイロードを確認します。

BadRequest メッセージは、リクエストに無効な値を含むフィールドがあるか、必須フィールドの値が欠落していることを示します。BadRequest の field_violations リストをチェックして、エラーのあるフィールドを確認します。各 field_violations エントリには、エラーの修正に役立つ情報が含まれています。

field

リクエスト内のフィールドの場所(スネークケースのパス構文)。

パスがリスト内のアイテム(repeated フィールド)を指している場合、そのインデックスはリスト名の後に角かっこ([...])で囲まれて表示されます。

たとえば、destinations[0].operating_account.account_id は destinations リストの最初のアイテムの operating_account の account_id です。

description

値がエラーの原因となった理由の説明。

reason

ErrorReason 列挙型(INVALID_HEX_ENCODING、INVALID_CURRENCY_CODE など)。

BadRequest の例

BadRequest メッセージを含む INVALID_ARGUMENT エラーのレスポンスの例を次に示します。field_violations は、エラーが数値ではない accountId であることを示しています。field 値 destinations[0].login_account.account_id は、フィールド違反のある accountId が destinations リストの最初の項目の login_account にあることを示しています。

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

BadRequest メッセージを含む INVALID_ARGUMENT エラーのレスポンスの例を次に示します。この場合、field_violations リストには次の 2 つのエラーが表示されます。

  1. 最初の event には、イベントの 2 番目のユーザー識別子で 16 進数エンコードされていない値が含まれています。

  2. 2 番目の event には、イベントの 3 番目のユーザー識別子で 16 進数でエンコードされていない値が含まれています。

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

リクエストが失敗した場合は、RequestInfo ペイロードを確認します。RequestInfo には、API リクエストを一意に識別する request_id が含まれています。

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

エラーをログに記録する場合やサポートに問い合わせる場合は、問題の診断に役立つリクエスト ID を含めてください。

ErrorInfo

ErrorInfo メッセージを確認して、他の標準の詳細ペイロードでキャプチャされない可能性のある追加情報を取得します。ErrorInfo ペイロードには、エラーに関する情報を含む metadata マップが含まれています。

たとえば、Data Manager API が有効になっていない Google Cloud プロジェクトの認証情報を使用した場合に発生する PERMISSION_DENIED エラーの ErrorInfo は次のようになります。ErrorInfo は、次のようなエラーに関する追加情報を提供します。

  • リクエストに関連付けられたプロジェクト(metadata.consumer の下)。
  • サービスの名前(metadata.serviceTitle の下)。
  • サービスを有効にできる URL(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"
        }
      },
      ...
    ]
  }
}

割り当てとレート制限のエラー

リクエストがプロジェクトの上限を超えると、API は RESOURCE_EXHAUSTED エラー(HTTP ステータス コード 429)を返します。ErrorInfo ペイロードは、metadata マップで上限を超えた詳細を提供します。

consumer
リクエストに関連付けられた Google Cloud プロジェクト。projects/PROJECT_NUMBER の形式。
quota_limit
上限を超えた割り当ての名前(IngestionMutateRequestsPerMinutePerProject、IngestionMutateRequestsPerDayPerProject など)。この値を使用して、アプリケーションが 1 分あたりの上限または 1 日の利用時間の上限を超えたかどうかを判断できます。上限名の完全なリストについては、プロジェクトの上限をご覧ください。
quota_location
割り当てが適用されるロケーション。Data Manager API の場合、これは常に global です。
quota_metric
上限に関連付けられている指標(datamanager.googleapis.com/ingestion_mutate_requests など)。
service
サービスの名前(datamanager.googleapis.com)。

リクエストが取り込み変更リクエストの 1 分あたりの上限を超えた場合の RESOURCE_EXHAUSTED エラー レスポンスの例を次に示します。

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

Help ペイロードと LocalizedMessage ペイロードを確認して、ドキュメントへのリンクとローカライズされたエラー メッセージを取得します。これにより、エラーを理解して修正できます。

たとえば、Data Manager API が有効になっていない Google Cloud プロジェクトの認証情報を使用した場合に発生する PERMISSION_DENIED エラーの Help と LocalizedMessage は次のようになります。Help ペイロードには、サービスを有効にできる URL が表示されます。LocalizedMessage にはエラーの説明が含まれます。

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

アクセスエラーの詳細

クライアント ライブラリのいずれかを使用している場合は、ヘルパー メソッドを使用して標準の詳細ペイロードを取得します。

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

gRPC のヘッダーサイズ エラーを処理する

取り込みリクエストまたは削除リクエストで多数のレコードの検証が失敗すると、Data Manager API はレスポンスの BadRequest ペイロードですべてのエラーを返します。

gRPC では、サービスはこれらのエラーの詳細を HTTP/2 レスポンス ヘッダー(メタデータ)で返します。デフォルトでは、gRPC クライアント ライブラリは受信ヘッダーを最大サイズ(通常は 8 ~ 10 KB)に制限します。エラーの詳細がこの上限を超えると、クライアントサイドの HTTP/2 トランスポートはエラー レスポンスを解析する前に失敗し、次のような例外をスローします。

Http2Exception: Header size exceeded max allowed size (10240)

クライアントはレスポンス ヘッダーを処理できないため、ストリームをキャンセルします(サーバーサイドのログに HTTP ステータス 499 Client Closed Request として表示されます)。アプリケーションは BadRequest エラーの詳細にアクセスできません。

この問題を解決してエラーの完全なリストを調べるには、受信メタデータの最大サイズ(16 MB など)を増やして gRPC クライアントを構成します。

.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)) {
  // ...
}

ノード

// 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)
)

エラー処理のベスト プラクティス

復元力のあるアプリケーションを構築するには、次のベスト プラクティスを実装します。

送信前に検証する
統合を構築または変更する場合は、validateOnly を true に設定してリクエストを送信し、データを取り込む前に高速フェイル エラーをキャッチします。
エラーの詳細を調べる
常に、BadRequest などの標準の詳細ペイロードのいずれかを探します。各標準詳細ペイロードには、エラーの原因を理解するのに役立つ情報が含まれています。
クライアント エラーとサーバーエラーを区別する

エラーの原因が実装(クライアント)の問題か、API(サーバー)の問題かを判断します。

  • クライアント エラー: INVALID_ARGUMENT、NOT_FOUND、PERMISSION_DENIED、FAILED_PRECONDITION、UNAUTHENTICATED などのコード。これらには、リクエストまたはアプリケーションの状態/認証情報の変更が必要です。問題に対処せずにリクエストを再試行しないでください。
  • サーバーエラー: UNAVAILABLE、INTERNAL、DEADLINE_EXCEEDED、UNKNOWN などのコード。これらは、API サービスの一時的な問題を示しています。
再試行戦略を実装する

エラーを再試行できるかどうかを判断し、再試行戦略を使用します。

  • 一時的なサーバーエラー(UNAVAILABLE、DEADLINE_EXCEEDED、INTERNAL、UNKNOWN、ABORTED など)と 1 分あたりのレート制限(RATE_LIMIT_EXCEEDED を含む RESOURCE_EXHAUSTED)の場合にのみ再試行します。

  • レート制限については、ErrorInfo の quota_limit を確認します。

    • 上限が 1 分あたり(IngestionMutateRequestsPerMinutePerProject など)の場合は、リクエストを一時停止し、ジッターを伴う指数バックオフを使用して再試行します。

    • 上限が毎日(IngestionMutateRequestsPerDayPerProject など)の場合は、すぐに再試行しないでください。1 日の割り当てが太平洋時間の午前 0 時にリセットされるまで、処理を一時停止します。

  • 指数バックオフ アルゴリズムを使用して、再試行の間隔を長くします。これにより、すでに負荷がかかっているサービスに過剰な負荷がかかるのを防ぐことができます。たとえば、1 秒、2 秒、4 秒と待機時間を増やしていき、再試行の最大回数または合計待機時間に達するまで繰り返します。

  • バックオフ遅延に少量のランダムな「ジッター」を追加して、多くのクライアントが同時に再試行する「Thundering Herd」問題を回避します。

徹底的にロギングする

すべての標準の詳細ペイロード(特にリクエスト ID)を含む、完全なエラー レスポンスをログに記録します。この情報は、必要に応じてデバッグを行い、Google サポートに問題を報告するために不可欠です。

ユーザー フィードバックを提供する

標準の詳細ペイロードのコードとメッセージに基づいて、アプリケーションのユーザーに明確で役立つフィードバックを提供します。たとえば、「エラーが発生しました」ではなく、「トランザクション ID がありません」や「宛先のアカウント ID が見つかりませんでした」などです。

これらのガイドラインに沿って、Data Manager API から返されるエラーを効果的に診断して処理することで、より安定したユーザー フレンドリーなアプリケーションを実現できます。