В этом руководстве рассказывается, как Data Manager API обрабатывает ошибки и сообщает о них. Понимание структуры и значения ошибок API имеет решающее значение для создания надежных приложений, которые могут корректно обрабатывать проблемы, от недействительных входных данных до временной недоступности сервиса.
В Data Manager API используется стандартная модель ошибок API Google, основанная на кодах статуса gRPC. Каждый ответ API, который приводит к ошибке, включает объект Status со следующими элементами:
- Числовой код ошибки.
- Сообщение об ошибке.
- Дополнительные сведения об ошибке (необязательно).
Канонические коды ошибок
В Data Manager API используется набор канонических кодов ошибок, определенных gRPC и HTTP. Эти коды указывают на тип ошибки. Всегда начинайте с проверки этого кода, чтобы понять суть проблемы.
Подробную информацию об этих кодах можно найти в руководстве по проектированию API — коды ошибок.
Модель быстрого отказа
В Data Manager API используется модель быстрого отказа. Если в запросе есть структурные ошибки или какая-либо запись не проходит проверку обязательного поля, весь запрос отклоняется и API не обрабатывает данные из него.
Сравнение с моделью частичного сбоя
Модель быстрого сбоя отличается от модели частичного сбоя, которая используется в некоторых других API Google, например в Google Ads API и Менеджер кампаний 360 API. В модели частичного сбоя запрос выполняется, даже если некоторые записи содержат ошибки, а ответ содержит сведения об ошибках для записей, которые не удалось обработать.
Хотя частичное выполнение может быть удобным, оно несет в себе значительные риски, поскольку модель частичного выполнения не предупреждает вас об ошибках заранее – вы должны явно проверять наличие ошибок в каждом ответе. Это может маскировать важные проблемы, поскольку запрос выполняется, даже если API отклоняет многие или даже все записи в запросе. Если значительная часть записей в запросе содержит ошибки, но вы не проверяете ответ, вы можете не знать о широко распространенных проблемах с вашими данными и обнаружить их только через несколько дней или недель, когда совокупные результаты не будут соответствовать вашим ожиданиям.
Модель быстрого сбоя позволяет избежать этих проблем, немедленно предупреждая вас о проблемах с вашими данными или интеграцией, чтобы вы могли принять соответствующие меры.
Как проверить наличие ошибок быстрого сбоя с помощью validateOnly
Большинство запросов на добавление и удаление поддерживают поле validateOnly. Если для параметра validateOnly задано значение true, Data Manager API выполняет те же базовые проверки, что и для обычного запроса, но не добавляет и не удаляет данные.
- Если в запросе есть ошибки, он не будет выполнен, и вы получите такое же сообщение об ошибке, как и при обычном запросе.
- Если запрос проходит проверку, он выполняется. В ответе будут содержаться все
fieldWarningsдля необязательных полей, как и в обычном запросе.
Используя validateOnly, вы можете:
- Протестируйте новую или обновленную интеграцию, не затрагивая текущие данные.
- Прежде чем повторно отправлять запрос, убедитесь, что ошибка устранена.
Обработка ошибок
Если запрос не выполняется, сделайте следующее:
Чтобы определить тип ошибки, проверьте код ошибки.
- Если вы используете gRPC, код ошибки находится в поле
codeобъектаStatus. Если вы используете клиентскую библиотеку, она может выдать определенный тип исключения, соответствующий коду ошибки. Например, клиентская библиотека для Java выдает ошибкуcom.google.api.gax.rpc.InvalidArgumentException, если код ошибки –INVALID_ARGUMENT. - Если вы используете REST, код ошибки находится в ответе об ошибке в поле
error.status, а соответствующий статус HTTP – в полеerror.code.
- Если вы используете gRPC, код ошибки находится в поле
Проверьте стандартные полезные данные для кода ошибки. Стандартные полезные нагрузки – это набор сообщений об ошибках в API Google. Они предоставляют вам подробную информацию об ошибках структурированным и последовательным образом. Каждая ошибка, возвращаемая Data Manager API, может содержать несколько стандартных сообщений с подробными сведениями. В клиентских библиотеках Data Manager API есть вспомогательные методы, позволяющие получать стандартные полезные нагрузки с подробными сведениями об ошибках.
Независимо от кода ошибки, мы рекомендуем проверять и регистрировать полезные нагрузки
ErrorInfo,RequestInfo,HelpиLocalizedMessage.- В
ErrorInfoможет быть информация, которой нет в других полезных нагрузках. RequestInfoсодержит идентификатор запроса, который может пригодиться при обращении в службу поддержки.HelpиLocalizedMessageсодержат ссылки и другие сведения, которые помогут вам устранить ошибку.
Кроме того, полезная нагрузка
BadRequestпомогает при ошибкахINVALID_ARGUMENT, поскольку содержит информацию о том, какие поля вызвали ошибку.- В
Предупреждения при приеме контента
Data Manager API принимает как можно больше запросов на загрузку. Если вы добавите необязательные данные, ошибки проверки в этих полях не приведут к сбою запроса. Например, если у товара в корзине отсутствует идентификатор товара продавца, API обрабатывает остальную часть запроса и возвращает предупреждение.
Ответ об успешной загрузке (код статуса HTTP 200) включает эти предупреждения в списке fieldWarnings. Каждая запись представляет собой объект FieldWarning со следующими полями:
fieldРасположение поля в запросе, в синтаксисе пути в змеином регистре.
Если путь указывает на элемент в списке (поле
repeated), его индекс указывается в квадратных скобках ([...]) после названия списка.Например,
events.events[0].cart_data.items[0].merchant_product_idуказывает на предупреждение, связанное с первым товаром в данных корзины первого события в запросе.descriptionОбъяснение, почему указанное значение вызвало предупреждение.
reasonЗначение перечисления
WarningReason, которое определяет тип предупреждения.
Пример с FieldWarning
Ниже приведен пример ответа на успешный запрос, содержащий предупреждение о том, что для одного из товаров в корзине отсутствует идентификатор товара продавца.
{
"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
Проверьте полезную нагрузку BadRequest, если запрос не выполняется с ошибкой INVALID_ARGUMENT (код статуса HTTP 400).
Сообщение BadRequest означает, что в запросе были поля с недопустимыми значениями или отсутствовало значение для обязательного поля. Проверьте список field_violations в BadRequest, чтобы узнать, в каких полях есть ошибки. Каждая запись field_violations содержит информацию, которая поможет вам исправить ошибку:
fieldРасположение поля в запросе, в синтаксисе пути в змеином регистре.
Если путь указывает на элемент в списке (поле
repeated), его индекс указывается в квадратных скобках ([...]) после названия списка.Например,
destinations[0].operating_account.account_id– этоaccount_idвoperating_accountпервого элемента в спискеdestinations.descriptionОбъяснение, почему значение вызвало ошибку.
reasonПеречисление
ErrorReason, напримерINVALID_HEX_ENCODINGилиINVALID_CURRENCY_CODE.
Примеры для слова "BadRequest"
Ниже приведен пример ответа на ошибку INVALID_ARGUMENT с сообщением BadRequest. field_violations указывает на то, что ошибка – это accountId, которое не является числом. Значение destinations[0].login_account.account_id в поле field указывает на то, что accountId с нарушением находится в поле login_account первого элемента в списке 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"
}
]
}
]
}
}
Вот ещё один пример ответа на ошибку INVALID_ARGUMENT с сообщением BadRequest. В этом случае в списке field_violations будут показаны две ошибки:
Первый параметр
eventимеет значение, которое не закодировано в шестнадцатеричном формате во втором идентификаторе пользователя события.Второй параметр
eventсодержит значение, которое не закодировано в шестнадцатеричном формате, в третьем идентификаторе пользователя события.
{
"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 содержит request_id, который уникальным образом идентифицирует ваш запрос к API.
{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "t-4490c640-dc5d-4c28-91c1-04a1cae0f49f"
}
При регистрации ошибок или обращении в службу поддержки обязательно указывайте идентификатор запроса, чтобы помочь в диагностике проблем.
ErrorInfo
Проверьте сообщение ErrorInfo, чтобы получить дополнительную информацию, которая может не содержаться в других стандартных полезных нагрузках. Полезная нагрузка ErrorInfo содержит карту metadata с информацией об ошибке.
Например, вот ErrorInfo для ошибки PERMISSION_DENIED, вызванной использованием учетных данных для проекта Google Cloud, в котором не включен Data Manager API. В 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. Это значение позволяет определить, превышено ли ограничение на количество запросов в минуту или дневное ограничение. Полный список названий лимитов приведен в разделе Лимиты проекта. quota_location- Местоположение, в котором применяется квота. Для Data Manager API это всегда
global. quota_metric- Показатель, связанный с ограничением, например
datamanager.googleapis.com/ingestion_mutate_requests. service- Название сервиса,
datamanager.googleapis.com.
Ниже приведен пример ответа с ошибкой RESOURCE_EXHAUSTED, когда запрос превышает поминутное ограничение на запросы mutate для загрузки.
{
"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, чтобы получить ссылки на документацию и локализованные сообщения об ошибках, которые помогут вам понять и устранить ошибку.
Например, вот Help и LocalizedMessage для ошибки PERMISSION_DENIED, вызванной использованием учетных данных для проекта Google Cloud, в котором не включен Data Manager API. Полезная нагрузка 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 КБ). Если сведения об ошибке превышают этот лимит, клиентский транспорт HTTP/2 завершается сбоем до обработки ответа об ошибке, вызывая исключение, например:
Http2Exception: Header size exceeded max allowed size (10240)
Поскольку клиент не может обработать заголовки ответа, он отменяет поток (в журналах на стороне сервера это выглядит как статус HTTP 499 Client Closed Request), и ваше приложение не может получить доступ к сведениям об ошибке BadRequest.
Чтобы устранить эту проблему и посмотреть полный список ошибок, увеличьте максимальный размер входящих метаданных в настройках клиента gRPC (например, до 16 МБ).
.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) и при превышении ограничений на количество запросов в минуту (RESOURCE_EXHAUSTEDсRATE_LIMIT_EXCEEDED).Чтобы узнать ограничения частоты запросов, проверьте
quota_limitвErrorInfo:Если лимит поминутный (например,
IngestionMutateRequestsPerMinutePerProject), приостановите запросы и повторите попытку, используя экспоненциальную выдержку с джиттером.Если ограничение дневное (например,
IngestionMutateRequestsPerDayPerProject), не повторяйте попытку сразу. Приостановите обработку до полуночи по тихоокеанскому времени, когда будет сброшена суточная квота.
Используйте алгоритм экспоненциальной выдержки, чтобы увеличивать интервалы между попытками. Это помогает избежать перегрузки и без того перегруженного сервиса. Например, подождите 1 секунду, затем 2 секунды, затем 4 секунды и так далее, пока не будет достигнуто максимальное количество повторных попыток или общее время ожидания.
Добавьте небольшое случайное значение к задержкам экспоненциальной выдержки, чтобы предотвратить проблему "грохочущего стада", когда многие клиенты повторяют попытку одновременно.
- Подробно записывайте данные
Зарегистрируйте полный ответ об ошибке, включая все стандартные полезные нагрузки, особенно идентификатор запроса. Эта информация необходима для отладки и отправки отчетов о проблемах в службу поддержки Google.
- Как оставить отзыв
На основе кодов и сообщений в стандартных полезных нагрузках предоставляйте пользователям приложения понятные и полезные отзывы. Например, вместо "Произошла ошибка" можно написать "Отсутствует идентификатор транзакции" или "Идентификатор аккаунта назначения не найден".
Следуя этим рекомендациям, вы сможете эффективно диагностировать и обрабатывать ошибки, возвращаемые Data Manager API, что приведет к созданию более стабильных и удобных приложений.