Z tego przewodnika dowiesz się, jak Data Manager API obsługuje błędy i przekazuje informacje o nich. Zrozumienie struktury i znaczenia błędów interfejsu API jest kluczowe do tworzenia niezawodnych aplikacji, które mogą sprawnie obsługiwać problemy, od nieprawidłowych danych wejściowych po tymczasową niedostępność usługi.
Data Manager API korzysta ze standardowego modelu błędów interfejsu Google API, który jest oparty
na kodach stanu gRPC. Każda odpowiedź interfejsu API, która powoduje błąd, zawiera obiekt Status z tymi informacjami:
- numeryczny kod błędu,
- komunikat o błędzie,
- opcjonalne, dodatkowe szczegóły błędu.
Kanoniczne kody błędów
Data Manager API używa zbioru kanonicznych kodów błędów zdefiniowanych przez gRPC i HTTP. Te kody zawierają ogólne informacje o typie błędu. Zawsze najpierw sprawdzaj ten kod, aby zrozumieć podstawowy charakter problemu.
Więcej informacji o tych kodach znajdziesz w API Design Guide – Kody błędów.
Obsługa błędów
Jeśli żądanie się nie powiedzie, wykonaj te czynności:
Sprawdź kod błędu, aby znaleźć typ błędu.
- Jeśli używasz gRPC, kod błędu znajduje się w polu
codeobiektuStatus. Jeśli używasz biblioteki klienta, może ona zgłosić określony typ wyjątku odpowiadający kodowi błędu. Na przykład biblioteka klienta w języku Java zgłasza wyjątekcom.google.api.gax.rpc.InvalidArgumentException, jeśli kod błędu toINVALID_ARGUMENT. - Jeśli używasz REST, kod błędu znajduje się w odpowiedzi o błędzie w polu
error.status, a odpowiedni stan HTTP znajduje się w poluerror.code.
- Jeśli używasz gRPC, kod błędu znajduje się w polu
Sprawdź standardowy ładunek szczegółów dla kodu błędu. Standardowe ładunki szczegółów to zbiór komunikatów o błędach z interfejsów API Google. Zawierają one szczegóły błędu w uporządkowany i spójny sposób. Każdy błąd z Data Manager API może mieć wiele standardowych komunikatów ładunku szczegółów. Biblioteki klienta Data Manager API mają metody pomocnicze do pobierania standardowych ładunków szczegółów z błędu.
Niezależnie od kodu błędu zalecamy sprawdzenie i zarejestrowanie ładunków
ErrorInfo,RequestInfo,Help, iLocalizedMessage.ErrorInfozawiera informacje, których nie ma w innych ładunkach.RequestInfozawiera identyfikator żądania, który jest przydatny, jeśli musisz skontaktować się z zespołem pomocy.HelpiLocalizedMessagezawierają linki i inne szczegóły, które pomogą Ci rozwiązać problem.
Dodatkowo ładunek
BadRequestjest przydatny w przypadku błędówINVALID_ARGUMENT, ponieważ zawiera informacje o tym, które pola spowodowały błąd.
Standardowe ładunki szczegółów
Najczęstsze standardowe ładunki szczegółów w Data Manager API to:
BadRequest
Sprawdź ładunek BadRequest, gdy żądanie się nie powiedzie z powodu błędu
INVALID_ARGUMENT (kod stanu HTTP 400).
Komunikat BadRequest wskazuje, że żądanie zawierało pola z nieprawidłowymi wartościami lub brakowało 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:
fieldLokalizacja pola w żądaniu, z użyciem składni ścieżki w notacji camel 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_idtoaccount_idwoperating_accountpierwszego elementu na liściedestinations.descriptionWyjaśnienie, dlaczego wartość spowodowała błąd.
reasonWyliczenie
ErrorReason, np.INVALID_HEX_ENCODINGlubINVALID_CURRENCY_CODE.
Przykłady BadRequest
Oto przykładowa odpowiedź na błąd INVALID_ARGUMENT z komunikatem BadRequest. Wartość 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 pola 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 kolejna przykładowa odpowiedź na błąd INVALID_ARGUMENT z komunikatem BadRequest. W tym przypadku lista field_violations zawiera 2 błędy:
Pierwsze
eventma wartość, która nie jest zakodowana w formacie szesnastkowym w drugim identyfikatorze użytkownika zdarzenia.Drugie
eventma wartość, która nie jest zakodowana w formacie szesnastkowym 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
Sprawdź ładunek RequestInfo, gdy żądanie się nie powiedzie. RequestInfo zawiera request_id, który jednoznacznie identyfikuje Twoje żą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ź komunikat ErrorInfo, aby uzyskać dodatkowe informacje, które
mogą nie być zawarte w innych standardowych ładunkach szczegółów. Ładunek ErrorInfo zawiera mapę metadata z informacjami o błędzie.
Oto na przykład ErrorInfo w przypadku błędu PERMISSION_DENIED spowodowanego użyciem danych logowania do projektu Google Cloud, w którym Data Manager API nie jest włączony. ErrorInfo zawiera dodatkowe informacje o błędzie, takie jak:
- projekt powiązany z żądaniem, w polu
metadata.consumer. - nazwa usługi, w polu
metadata.serviceTitle. - adres URL, pod którym można włączyć usługę, w polu
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"
}
},
...
]
}
}
Help i LocalizedMessage
Sprawdź ładunki Help i LocalizedMessage, aby uzyskać linki do
dokumentacji i zlokalizowane komunikaty o błędach, które pomogą Ci zrozumieć i naprawić
błąd.
Oto na przykład Help i LocalizedMessage w przypadku błędu PERMISSION_DENIED spowodowanego użyciem danych logowania do projektu Google Cloud, w którym Data Manager API nie jest włączony. Ł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"
}
]
},
...
]
}
}
Dostęp do szczegółów błędu
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...
// 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...
}
...
}
Sprawdzone metody obsługi błędów
Aby tworzyć odporne aplikacje, stosuj te sprawdzone metody.
- Sprawdzaj szczegóły błędu
- Zawsze szukaj jednego ze standardowych ładunków szczegółów takich jak
BadRequest. Każdy standardowy ładunek szczegółów zawiera informacje, które pomogą Ci zrozumieć przyczynę błędu. - Odróżniaj błędy klienta od błędów 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. Wskazują one na tymczasowy problem z usługą interfejsu API.
- Błędy klienta: kody takie jak
- Wdróż strategię ponawiania
Określ, czy można ponowić próbę wykonania żądania, i zastosuj strategię ponawiania.
- Ponawiaj próbę tylko w przypadku przejściowych błędów serwera, takich jak
UNAVAILABLE,DEADLINE_EXCEEDED,INTERNAL,UNKNOWNiABORTED. - Użyj algorytmu wzrastającego czasu do ponowienia, aby odczekać coraz dłuższe okresy między ponownymi próbami. Pomaga to uniknąć przeciążenia już obciążonej usługi. Na przykład odczekaj 1 s, potem 2 s, potem 4 s, aż do osiągnięcia maksymalnej liczby ponownych prób lub łącznego czasu oczekiwania.
- Dodaj niewielką losową ilość „jittera” do opóźnień wycofywania, aby zapobiec problemowi „stada”, w którym wielu klientów ponawia próbę jednocześnie.
- Ponawiaj próbę tylko w przypadku przejściowych błędów serwera, takich jak
- Rejestruj szczegółowo
Zarejestruj pełną odpowiedź o błędzie, w tym wszystkie standardowe ładunki szczegółów, a zwłaszcza identyfikator żądania. Te informacje są niezbędne do debugowania i zgłaszania problemów zespołowi pomocy Google.
- Przekazuj opinie użytkowników
Na podstawie kodów i komunikatów w standardowych ładunkach szczegółów przekazuj użytkownikom aplikacji jasne i przydatne informacje. Na przykład zamiast „Wystąpił błąd” możesz napisać „Brakowało identyfikatora transakcji” lub „Nie znaleziono identyfikatora konta miejsca docelowego”.
Postępując zgodnie z tymi wytycznymi, możesz skutecznie diagnozować i obsługiwać błędy zwracane przez Data Manager API, co pozwoli Ci tworzyć bardziej stabilne i przyjazne dla użytkownika aplikacje.