Informacje o błędach interfejsu API

Z tego przewodnika dowiesz się, jak interfejs Data Manager API obsługuje i komunikuje błędy. Zrozumienie struktury i znaczenia błędów interfejsu API jest kluczowe dla tworzenia solidnych aplikacji, które mogą bezproblemowo radzić sobie z problemami, od nieprawidłowych danych wejściowych po tymczasową niedostępność usługi.

Interfejs Data Manager API jest zgodny ze standardowym modelem błędów interfejsu API Google, który jest oparty na kodach stanu gRPC. Każda odpowiedź interfejsu API, która powoduje błąd, zawiera obiekt Status z:

  • Numeryczny kod błędu.
  • komunikat o błędzie,
  • Opcjonalne, dodatkowe szczegóły błędu.

Kanoniczne kody błędów

Interfejs Data Manager API używa zestawu kanonicznych kodów błędów zdefiniowanych przez gRPC i HTTP. Te kody wskazują ogólny typ błędu. Zawsze najpierw sprawdzaj ten kod, aby zrozumieć podstawowy charakter problemu.

Więcej informacji o tych kodach znajdziesz w przewodniku API Design Guide – kody błędów.

Model szybkiego niepowodzenia

Interfejs Data Manager API używa modelu szybkiego niepowodzenia. Jeśli żądanie zawiera błędy strukturalne lub jeśli którykolwiek rekord nie przejdzie weryfikacji wymaganego pola, całe żądanie się nie powiedzie, a interfejs API nie przetworzy żadnych danych w tym żądaniu.

Porównanie z modelem częściowego niepowodzenia

Model szybkiego niepowodzenia różni się od modelu częściowego niepowodzenia w niektórych innych interfejsach API Google, takich jak interfejs Google Ads API i Campaign Manager 360 API. W modelu częściowego niepowodzenia żądanie jest realizowane, nawet jeśli niektóre rekordy zawierają błędy, a odpowiedź zawiera szczegóły błędów w przypadku nieudanych rekordów.

Chociaż częściowe niepowodzenie może być wygodne, wiąże się ze znacznym ryzykiem, ponieważ model częściowego niepowodzenia nie ostrzega proaktywnie o błędach – musisz wyraźnie sprawdzać, czy w każdej odpowiedzi nie ma błędów. Może to maskować ważne problemy, ponieważ żądanie zostanie zrealizowane, nawet jeśli interfejs API odrzuci wiele lub nawet wszystkie rekordy w żądaniu. Jeśli znaczna część rekordów w żądaniu zawiera błędy, ale nie sprawdzisz odpowiedzi, możesz nie zdawać sobie sprawy z powszechnych problemów z danymi i odkryć je dopiero po kilku dniach lub tygodniach, gdy skumulowane wyniki nie będą zgodne z oczekiwaniami.

Model szybkiego niepowodzenia pozwala uniknąć tych pułapek, ponieważ natychmiast powiadamia o problemach z danymi lub integracją, dzięki czemu możesz podjąć odpowiednie działania.

Sprawdzanie błędów typu „fast-fail” za pomocą validateOnly

Większość żądań przetwarzania i usuwania obsługuje pole validateOnly. Gdy ustawisz parametr validateOnly na true, interfejs Data Manager API przeprowadzi te same podstawowe testy weryfikacyjne co w przypadku zwykłego żądania, ale nie będzie pozyskiwać ani usuwać żadnych danych.

  • Jeśli żądanie zawiera błędy, nie powiedzie się i zwróci ten sam błąd, który zostałby zwrócony w przypadku zwykłego żądania.
  • Jeśli żądanie przejdzie weryfikację, zostanie zrealizowane. Odpowiedź zawiera wszystkie obiekty fieldWarnings dla pól opcjonalnych, tak jak w przypadku zwykłego żądania.

Korzystaj z validateOnly, aby:

  • Przetestuj nową lub zaktualizowaną integrację bez wpływu na dane na żywo.
  • Zanim ponownie wyślesz prośbę, sprawdź, czy błąd został naprawiony.

Obsługuj błędy

Jeśli żądanie się nie powiedzie, wykonaj te czynności:

  1. Sprawdź kod błędu, aby dowiedzieć się, jakiego rodzaju jest to błąd.

    • Jeśli używasz gRPC, kod błędu znajduje się w polu code obiektu Status. Jeśli używasz biblioteki klienta, może ona zgłosić określony typ wyjątku, który odpowiada kodowi błędu. Na przykład biblioteka klienta dla języka Java zgłasza błąd com.google.api.gax.rpc.InvalidArgumentException, jeśli kod błędu to INVALID_ARGUMENT.
    • Jeśli używasz REST, kod błędu znajduje się w odpowiedzi na błąd w error.status, a odpowiadający mu stan HTTP w error.code.
  2. Sprawdź standardowe szczegółowe dane kodu błędu. Standardowe ładunki szczegółów to zestaw komunikatów o błędach z interfejsów API Google. Zawierają one szczegółowe informacje o błędach w uporządkowany i spójny sposób. Każdy błąd z interfejsu Data Manager API może zawierać kilka standardowych komunikatów ze szczegółowymi informacjami. Biblioteki klienta interfejsu Data Manager API zawierają metody pomocnicze, które umożliwiają uzyskanie standardowych szczegółowych danych o błędzie.

    Niezależnie od kodu błędu zalecamy sprawdzenie i zarejestrowanie ładunków ErrorInfo, RequestInfo, Help i LocalizedMessage.

    • ErrorInfo zawiera informacje, których może nie być w innych ładunkach.
    • RequestInfo zawiera identyfikator prośby, który jest przydatny, jeśli chcesz skontaktować się z zespołem pomocy.
    • Help i LocalizedMessage zawierają linki i inne szczegóły, które pomogą Ci rozwiązać problem.

    Dodatkowo ładunek BadRequest jest przydatny w przypadku błędów INVALID_ARGUMENT, ponieważ zawiera informacje o tym, które pola spowodowały błąd.

Ostrzeżenia dotyczące przetwarzania

Interfejs Data Manager API akceptuje jak największą część żądania pozyskiwania danych. Jeśli podasz dane, które nie są wymagane, błędy weryfikacji tych pól nie spowodują niepowodzenia żądania. Jeśli na przykład w elemencie koszyka brakuje identyfikatora produktu sprzedawcy, interfejs API przetworzy pozostałą część żądania i wyświetli ostrzeżenie.

Odpowiedź informująca o powodzeniu przetwarzania (kod stanu HTTP 200) zawiera te ostrzeżenia na liście fieldWarnings. Każdy wpis jest obiektem FieldWarning z tymi polami:

field

Lokalizacja pola w żądaniu, w składni ścieżki snake_case.

Jeśli ścieżka wskazuje element na liście (pole repeated), jego indeks jest wyświetlany w nawiasach kwadratowych ([...]) po nazwie listy.

Na przykład events.events[0].cart_data.items[0].merchant_product_id identyfikuje ostrzeżenie związane z pierwszym produktem w danych koszyka pierwszego zdarzenia w żądaniu.

description

Wyjaśnienie, dlaczego podana wartość spowodowała ostrzeżenie.

reason

Wartość wyliczeniowa WarningReason, która określa typ ostrzeżenia.

Przykład z użyciem FieldWarning

Oto przykładowa odpowiedź na żądanie pozyskania, które zakończyło się powodzeniem, ale zawiera ostrzeżenie, ponieważ w przypadku jednego z produktów w koszyku brakowało identyfikatora produktu sprzedawcy.

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

Ładunki ze szczegółami standardowymi

Najczęstsze standardowe ładunki szczegółowe w przypadku interfejsu Data Manager API to:

BadRequest

Jeśli żądanie nie powiedzie się i zostanie zwrócony błąd INVALID_ARGUMENT (kod stanu HTTP 400), sprawdź, czy w ładunku występuje BadRequest.

Komunikat BadRequest oznacza, że żądanie zawierało pola z nieprawidłowymi wartościami lub brakowało w nim wartości wymaganego pola. Sprawdź listę field_violations w BadRequest, aby dowiedzieć się, które pola zawierają błędy. Każdy wpis field_violations zawiera informacje, które pomogą Ci naprawić błąd:

field

Lokalizacja pola w żądaniu, w składni ścieżki w formacie snake_case.

Jeśli ścieżka wskazuje element na liście (pole repeated), jego indeks jest wyświetlany w nawiasach kwadratowych ([...]) po nazwie listy.

Na przykład destinations[0].operating_account.account_id to account_id w operating_account pierwszego elementu na liście destinations.

description

Wyjaśnienie, dlaczego wartość spowodowała błąd.

reason

Typ wyliczeniowy ErrorReason, np. INVALID_HEX_ENCODING lub INVALID_CURRENCY_CODE.

Przykłady: BadRequest

Oto przykładowa odpowiedź na błąd INVALID_ARGUMENT z komunikatem BadRequest. field_violations wskazuje, że błąd to accountId, który nie jest liczbą. Wartość field destinations[0].login_account.account_id wskazuje, że accountId z naruszeniem zasad dotyczących pól znajduje się w login_account pierwszego elementu na liście 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"
          }
        ]
      }
    ]
  }
}

Oto kolejny przykład odpowiedzi na błąd INVALID_ARGUMENT z komunikatem BadRequest. W takim przypadku na liście field_violations pojawią się 2 błędy:

  1. Pierwszy parametr event ma wartość, która nie jest zakodowana szesnastkowo w drugim identyfikatorze użytkownika zdarzenia.

  2. Drugi parametr event ma wartość, która nie jest zakodowana szesnastkowo w trzecim identyfikatorze użytkownika zdarzenia.

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

Jeśli żądanie się nie powiedzie, sprawdź ładunek RequestInfo. RequestInfo zawiera request_id, który jednoznacznie identyfikuje żądanie do interfejsu API.

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

Podczas rejestrowania błędów lub kontaktowania się z zespołem pomocy podaj identyfikator żądania, aby ułatwić diagnozowanie problemów.

ErrorInfo

Sprawdź, czy jest komunikat ErrorInfo, aby uzyskać dodatkowe informacje, które mogą nie być zawarte w innych standardowych ładunkach szczegółowych. Ładunek ErrorInfo zawiera mapę metadata z informacjami o błędzie.

Oto na przykład ErrorInfo błędu PERMISSION_DENIED spowodowanego użyciem danych logowania do projektu Google Cloud, w którym interfejs Data Manager API nie jest włączony. ErrorInfo zawiera dodatkowe informacje o błędzie, takie jak:

  • Projekt powiązany z żądaniem, w ramach metadata.consumer.
  • Nazwa usługi, w sekcji metadata.serviceTitle.
  • Adres URL, pod którym można włączyć usługę, w sekcji 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"
        }
      },
      ...
    ]
  }
}

Błędy dotyczące limitów i ograniczeń liczby żądań

Gdy żądanie przekracza limit projektu, interfejs API zwraca błąd RESOURCE_EXHAUSTED (kod stanu HTTP 429). Ładunek ErrorInfo zawiera szczegółowe informacje o tym, który limit został przekroczony, w mapie metadata:

consumer
Projekt Google Cloud powiązany z żądaniem, sformatowany jako projects/PROJECT_NUMBER.
quota_limit
Nazwa przekroczonego limitu, np. IngestionMutateRequestsPerMinutePerProject lub IngestionMutateRequestsPerDayPerProject. Możesz użyć tej wartości, aby określić, czy aplikacja przekroczyła limit minutowy czy limit dzienny. Pełną listę nazw limitów znajdziesz w sekcji Limity projektów.
quota_location
Lokalizacja, w której obowiązuje limit. W przypadku interfejsu Data Manager API jest to zawsze global.
quota_metric
Wskaźnik powiązany z limitem, np. datamanager.googleapis.com/ingestion_mutate_requests.
service
Nazwa usługi: datamanager.googleapis.com.

Oto przykład odpowiedzi z błędem RESOURCE_EXHAUSTED, gdy żądanie przekracza limit żądań modyfikacji pozyskiwania na minutę:

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

Sprawdź ładunki Help i LocalizedMessage, aby uzyskać linki do dokumentacji i zlokalizowanych komunikatów o błędach, które pomogą Ci zrozumieć i naprawić błąd.

Oto przykładowe wartości Help i LocalizedMessage w przypadku błędu PERMISSION_DENIED spowodowanego użyciem danych logowania do projektu Google Cloud, w którym nie jest włączony interfejs Data Manager API. Ładunek Help zawiera adres URL, pod którym można włączyć usługę, a LocalizedMessage zawiera opis błędu.

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

Szczegóły błędu dostępu

Jeśli używasz jednej z bibliotek klienta, użyj metod pomocniczych, aby uzyskać standardowe ładunki szczegółów.

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

Obsługa błędów dotyczących rozmiaru nagłówka w gRPC

Jeśli duża liczba rekordów w żądaniu pozyskania lub usunięcia nie przejdzie weryfikacji, interfejs Data Manager API zwróci wszystkie błędy w ładunku BadRequest odpowiedzi.

W gRPC usługa zwraca te szczegóły błędu w nagłówkach odpowiedzi HTTP/2 (metadanych). Domyślnie biblioteki klienta gRPC ograniczają rozmiar przychodzących nagłówków do maksymalnego rozmiaru (zwykle 8–10 KB). Jeśli szczegóły błędu przekraczają ten limit, transport HTTP/2 po stronie klienta kończy się niepowodzeniem przed przeanalizowaniem odpowiedzi na błąd i zgłasza wyjątek, na przykład:

Http2Exception: Header size exceeded max allowed size (10240)

Ponieważ klient nie może przetworzyć nagłówków odpowiedzi, anuluje strumień (co w logach po stronie serwera jest widoczne jako stan HTTP 499 Client Closed Request), a aplikacja nie może uzyskać dostępu do szczegółów błędu BadRequest.

Aby rozwiązać ten problem i sprawdzić pełną listę błędów, skonfiguruj klienta gRPC ze zwiększonym maksymalnym rozmiarem przychodzących metadanych (np. 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)) {
  // ...
}

Węzeł

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

Sprawdzone metody obsługi błędów

Aby tworzyć odporne aplikacje, stosuj te sprawdzone metody.

Sprawdzanie przed wysłaniem
Podczas tworzenia lub zmieniania integracji wysyłaj żądania z parametrem validateOnly ustawionym na true, aby wykrywać błędy powodujące szybkie niepowodzenie przed przetworzeniem danych.
Sprawdzanie szczegółów błędu
Zawsze szukaj jednego ze standardowych ładunków szczegółowych, takich jak BadRequest. Każdy standardowy ładunek szczegółów zawiera informacje, które pomogą Ci zrozumieć przyczynę błędu.
Rozróżnianie błędów klienta i serwera

Określ, czy błąd jest spowodowany problemem z implementacją (klientem) czy z interfejsem API (serwerem).

  • Błędy klienta: kody takie jak INVALID_ARGUMENT, NOT_FOUND, PERMISSION_DENIED, FAILED_PRECONDITION, UNAUTHENTICATED. Wymagają one zmian w żądaniu lub stanie/danych logowania aplikacji. Nie ponawiaj żądania bez rozwiązania problemu.
  • Błędy serwera: kody takie jak UNAVAILABLE, INTERNAL, DEADLINE_EXCEEDED, UNKNOWN. Sugerują one tymczasowy problem z usługą interfejsu API.
Wdrażanie strategii ponawiania prób

Sprawdź, czy można ponowić próbę, i użyj strategii ponawiania.

  • Ponawiaj próby tylko w przypadku przejściowych błędów serwera (takich jak UNAVAILABLE, DEADLINE_EXCEEDED, INTERNAL, UNKNOWN i ABORTED) oraz limitów żądań na minutę (RESOURCE_EXHAUSTED z RATE_LIMIT_EXCEEDED).

  • Aby sprawdzić limity liczby żądań, sprawdź quota_limit w ErrorInfo:

    • Jeśli limit jest na minutę (np. IngestionMutateRequestsPerMinutePerProject), wstrzymaj żądania i spróbuj ponownie, używając wzrastającego czasu do ponowienia z fluktuacją.

    • Jeśli limit jest dzienny (np. IngestionMutateRequestsPerDayPerProject), nie próbuj ponownie od razu. Wstrzymaj przetwarzanie do czasu zresetowania dziennego limitu o północy czasu pacyficznego.

  • Użyj algorytmu wzrastającego czasu do ponowienia, aby wydłużać czas oczekiwania między kolejnymi próbami. Pomaga to uniknąć przeciążenia i tak już obciążonej usługi. Na przykład odczekaj 1 s, potem 2 s, potem 4 s, aż do osiągnięcia maksymalnej liczby prób lub łącznego czasu oczekiwania.

  • Dodaj niewielką losową wartość „jitter” do opóźnień wycofywania, aby zapobiec problemowi „thundering herd”, gdy wielu klientów ponawia próbę jednocześnie.

Dokładne zapisywanie danych

Zapisz pełną odpowiedź o błędzie, w tym wszystkie standardowe ładunki szczegółowe, a zwłaszcza identyfikator żądania. Te informacje są niezbędne do debugowania i zgłaszania problemów zespołowi pomocy Google.

Przesyłanie opinii użytkowników

Na podstawie kodów i komunikatów w standardowych ładunkach szczegółowych przekazuj użytkownikom aplikacji jasne i przydatne informacje. Na przykład zamiast „Wystąpił błąd” możesz powiedzieć „Brak identyfikatora transakcji” lub „Nie znaleziono identyfikatora konta docelowego”.

Dzięki przestrzeganiu tych wskazówek możesz skutecznie diagnozować i obsługiwać błędy zwracane przez interfejs Data Manager API, co pozwoli Ci tworzyć bardziej stabilne i przyjazne dla użytkownika aplikacje.