API エラーについて

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

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

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

標準的なエラーコード

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

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

フェイルファスト モデル

Data Manager API では、フェイルファスト モデルを使用します。リクエスト内のレコードのいずれかが基本的な検証に失敗すると、リクエスト全体が失敗し、API はそのリクエスト内のデータを処理しません。

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

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

フェイルファスト モデルでは、データまたは統合に関する問題がすぐに通知されるため、適切な対応を取ることができます。

エラーを処理する

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

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

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

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

    • ErrorInfo には、他のペイロードに含まれていない情報が含まれている場合があります。
    • RequestInfo にはリクエスト ID が含まれています。これは、 サポートに問い合わせる場合に役立ちます。
    • HelpLocalizedMessage には、エラーの解決に役立つリンクやその他の詳細が含まれています。

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

標準詳細ペイロード

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

BadRequest

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

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

field

リクエスト内のフィールドの場所(キャメルケースのパス構文を使用)。

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

たとえば、destinations[0].operating_account.account_id は、 account_id リストの最初の項目の operating_account 内の destinations です。

description

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

reason

ErrorReason 列挙型(INVALID_HEX_ENCODINGINVALID_CURRENCY_CODE など)。

BadRequest の例

次に、BadRequest メッセージを含む INVALID_ARGUMENT エラーのレスポンスの例を示します。field_violations は、エラーが数値ではない accountId であることを示しています。fielddestinations[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 番目の ユーザー ID で 16 進数エンコードされていない値が含まれています。

  2. 2 番目の event には、イベントの 3 番目の ユーザー ID で 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"
        }
      },
      ...
    ]
  }
}

HelpLocalizedMessage

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

たとえば、Data Manager API が有効になっていない Google Cloud プロジェクトの認証情報を使用したために発生した PERMISSION_DENIED エラーの HelpLocalizedMessage は次のようになります。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...

            // 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'...

  // 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 = invalidArgumentException.getErrorDetails().getRequestInfo();
  if (requestInfo != null) {
    String requestId = requestInfo.getRequestId();
    // Log the requestId...
  }
  ...
}

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

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

エラーの詳細を確認する
`BadRequest` などの標準詳細 ペイロードのいずれかを探します。各標準詳細ペイロードには、エラーの原因を理解するのに役立つ情報が含まれています。
クライアント エラーとサーバー エラーを区別する

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

  • クライアント エラー: INVALID_ARGUMENTNOT_FOUNDPERMISSION_DENIEDFAILED_PRECONDITIONUNAUTHENTICATED などのコード。これらには、リクエストまたはアプリケーションの状態/認証情報の変更が必要です。 問題を解決せずにリクエストを再試行しないでください。
  • サーバー エラー: UNAVAILABLEINTERNALDEADLINE_EXCEEDEDUNKNOWN などのコード。これらは、API サービスの一時的な問題を示しています。
再試行方法を実装する

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

  • UNAVAILABLEDEADLINE_EXCEEDEDINTERNALUNKNOWNABORTED などの一時的なサーバー エラーの場合にのみ再試行します。
  • 指数バックオフ アルゴリズムを使用して、再試行の間隔を長くします 。これにより、すでに負荷の高いサービスに過負荷がかかるのを防ぐことができます。たとえば、1 秒待ってから 2 秒、4 秒と、再試行の最大回数または合計待機時間に達するまで続けます。
  • バックオフ遅延に小さなランダムな「ジッター」を追加して、多くのクライアントが同時に再試行する「Thundering Herd」の問題を防ぎます。
徹底的にログに記録する

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

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

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

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