Panduan ini menjelaskan cara Data Manager API menangani dan mengomunikasikan error. Memahami struktur dan arti error API sangat penting untuk membangun aplikasi yang tangguh yang dapat menangani masalah dengan baik, mulai dari input yang tidak valid hingga ketidaktersediaan layanan sementara.
Data Manager API mengikuti model error Google API standar, yang didasarkan pada kode Status gRPC. Setiap respons API yang menghasilkan
error menyertakan objek Status dengan:
- Kode error numerik.
- Pesan error.
- Opsional, detail error tambahan.
Kode error kanonis
Data Manager API menggunakan serangkaian kode error kanonis yang ditentukan oleh gRPC dan HTTP. Kode ini memberikan indikasi umum tentang jenis error. Anda harus selalu memeriksa kode ini terlebih dahulu untuk memahami sifat mendasar dari masalah tersebut.
Untuk mengetahui detail selengkapnya tentang kode ini, lihat Panduan Desain API - Kode error.
Menangani error
Ikuti langkah-langkah berikut jika permintaan gagal:
Periksa kode error untuk menemukan jenis error.
- Jika Anda menggunakan gRPC, kode error ada di kolom
codepadaStatus. Jika Anda menggunakan library klien, library tersebut dapat memunculkan jenis pengecualian tertentu yang sesuai dengan kode error. Misalnya, library klien untuk Java akan menampilkancom.google.api.gax.rpc.InvalidArgumentExceptionjika kode errornya adalahINVALID_ARGUMENT. - Jika Anda menggunakan REST, kode error ada dalam respons error di
error.status, dan status HTTP yang sesuai ada dierror.code.
- Jika Anda menggunakan gRPC, kode error ada di kolom
Periksa payload detail standar untuk kode error. Payload detail standar adalah sekumpulan pesan untuk error dari Google API. Hal ini memberi Anda detail error dengan cara yang terstruktur dan konsisten. Setiap error dari Data Manager API mungkin memiliki beberapa pesan payload detail standar. Library klien Data Manager API memiliki metode helper untuk mendapatkan payload detail standar dari error.
Apa pun kode errornya, sebaiknya periksa dan catat payload
ErrorInfo,RequestInfo,Help, danLocalizedMessage.ErrorInfomemiliki informasi yang mungkin tidak ada di payload lain.RequestInfomemiliki ID permintaan, yang berguna jika Anda perlu menghubungi dukungan.HelpdanLocalizedMessageberisi link dan detail lainnya untuk membantu Anda mengatasi error.
Selain itu, payload
BadRequest,QuotaFailure, danRetryInfoberguna untuk kode error tertentu:- Jika kode statusnya adalah
INVALID_ARGUMENT, periksa payloadBadRequestuntuk mengetahui informasi tentang kolom mana yang menyebabkan error. - Jika kode statusnya adalah
RESOURCE_EXHAUSTED, periksa payloadQuotaFailuredanRetryInfountuk mendapatkan informasi kuota dan rekomendasi penundaan percobaan ulang.
Payload detail standar
Payload detail standar yang paling umum untuk Data Manager API adalah:
BadRequest
Periksa payload BadRequest saat permintaan gagal dengan
INVALID_ARGUMENT (kode status HTTP 400).
Pesan BadRequest menunjukkan bahwa permintaan memiliki kolom dengan nilai yang buruk, atau tidak memiliki nilai untuk kolom wajib diisi. Periksa daftar field_violations di
BadRequest untuk menemukan kolom mana yang memiliki error. Setiap entri field_violations
memiliki informasi untuk membantu Anda memperbaiki error:
fieldLokasi kolom dalam permintaan, menggunakan sintaks jalur camel case.
Jika jalur mengarah ke item dalam daftar (kolom
repeated), indeksnya akan ditampilkan dalam tanda kurung siku ([...]) setelah nama daftar.Misalnya,
destinations[0].operating_account.account_idadalahaccount_iddalamoperating_accountitem pertama dalam daftardestinations.descriptionPenjelasan mengapa nilai menyebabkan error.
reasonEnum
ErrorReason, sepertiINVALID_HEX_ENCODINGatauINVALID_CURRENCY_CODE.
Contoh BadRequest
Berikut adalah contoh respons untuk error INVALID_ARGUMENT dengan pesan BadRequest. field_violations menunjukkan bahwa error tersebut adalah accountId yang bukan
angka. Nilai field destinations[0].login_account.account_id menunjukkan bahwa
accountId dengan pelanggaran kolom ada di login_account item pertama
dalam daftar 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"
}
]
}
]
}
}
Berikut contoh respons lain dari error INVALID_ARGUMENT dengan pesan
BadRequest. Dalam hal ini, daftar field_violations menampilkan dua
kesalahan:
eventpertama memiliki nilai yang tidak dienkode hex pada ID pengguna kedua peristiwa.eventkedua memiliki nilai yang tidak dienkode hex pada ID pengguna ketiga peristiwa.
{
"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"
}
]
}
]
}
}
QuotaFailure dan RetryInfo
Periksa payload QuotaFailure dan RetryInfo saat permintaan gagal
dengan RESOURCE_EXHAUSTED (kode status HTTP 429).
Pesan QuotaFailure menunjukkan bahwa resource telah habis
(misalnya, Anda telah melampaui kuota), atau sistem mengalami kelebihan beban. Periksa
daftar violations untuk menentukan kuota mana yang terlampaui.
Error juga dapat berisi pesan RetryInfo, yang menunjukkan retry_delay yang direkomendasikan
untuk mencoba kembali permintaan.
RequestInfo
Periksa payload RequestInfo setiap kali permintaan gagal. RequestInfo
berisi request_id yang secara unik mengidentifikasi permintaan API Anda.
{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "t-4490c640-dc5d-4c28-91c1-04a1cae0f49f"
}
Saat mencatat error atau menghubungi dukungan, pastikan untuk menyertakan ID permintaan untuk membantu mendiagnosis masalah.
ErrorInfo
Periksa pesan ErrorInfo untuk mengambil informasi tambahan yang mungkin tidak tercatat dalam payload detail standar lainnya. Payload ErrorInfo
berisi peta metadata dengan informasi tentang error.
Misalnya, berikut ErrorInfo untuk kegagalan PERMISSION_DENIED yang disebabkan oleh
penggunaan kredensial untuk project Google Cloud yang tidak mengaktifkan Data Manager API. ErrorInfo memberikan informasi tambahan tentang error, seperti:
- Project yang terkait dengan permintaan, di bagian
metadata.consumer. - Nama layanan, di bagian
metadata.serviceTitle. - URL tempat layanan dapat diaktifkan, di bagian
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.developers.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.developers.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER"
}
},
...
]
}
}
Help dan LocalizedMessage
Periksa payload Help dan LocalizedMessage untuk mendapatkan link ke dokumentasi dan pesan error yang dilokalkan yang membantu Anda memahami dan memperbaiki error.
Misalnya, berikut Help dan LocalizedMessage untuk kegagalan PERMISSION_DENIED yang disebabkan oleh penggunaan kredensial untuk project Google Cloud yang Data Manager API-nya tidak diaktifkan. Payload Help menampilkan URL tempat layanan dapat diaktifkan, dan LocalizedMessage memiliki deskripsi error.
{
"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.developers.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.developers.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 developers console API activation",
"url": "https://console.developers.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER"
}
]
},
...
]
}
}
Mengakses detail error
Jika Anda menggunakan salah satu library klien, gunakan metode helper untuk mendapatkan payload detail standar.
.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.QuotaFailure)
{
Google.Rpc.QuotaFailure quotaFailure = (Google.Rpc.QuotaFailure)detail;
foreach (
Google.Rpc.QuotaFailure.Types.Violation violation in quotaFailure.Violations
)
{
// Access attributes such as violation.Subject and violation.QuotaId
}
}
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.QuotaFailureException quotaFailureException) {
// Gets the standard QuotaFailure payload from the exception.
QuotaFailure quotaFailure = quotaFailureException.getErrorDetails().getQuotaFailure();
for (int i = 0; i < quotaFailure.getViolationsCount(); i++) {
QuotaFailure.Violation violation = quotaFailure.getViolations(i);
// Access attributes such as violation.getSubject() and violation.getQuotaId()
}
// Gets the standard RequestInfo payload from the exception.
RequestInfo requestInfo = quotaFailureException.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.
...
}
Praktik terbaik untuk penanganan error
Untuk membangun aplikasi yang tangguh, terapkan praktik terbaik berikut.
- Memeriksa detail error
- Selalu cari salah satu payload detail standar seperti
BadRequest. Setiap payload detail standar berisi informasi untuk membantu Anda memahami penyebab error. - Membedakan error klien dari error server
Tentukan apakah error disebabkan oleh masalah pada penerapan Anda (klien) atau masalah pada API (server).
- Error klien: Kode seperti
INVALID_ARGUMENT,NOT_FOUND,PERMISSION_DENIED,FAILED_PRECONDITION,UNAUTHENTICATED. Error ini memerlukan perubahan pada permintaan atau status/kredensial aplikasi Anda. Jangan coba lagi permintaan tanpa mengatasi masalahnya. - Error server: Kode seperti
UNAVAILABLE,INTERNAL,DEADLINE_EXCEEDED,UNKNOWN. Error ini menunjukkan masalah sementara pada layanan API.
- Error klien: Kode seperti
- Menerapkan strategi percobaan ulang
Tentukan apakah error dapat dicoba lagi, dan gunakan strategi percobaan ulang.
- Coba lagi hanya untuk error server sementara seperti
UNAVAILABLE,DEADLINE_EXCEEDED,INTERNAL,UNKNOWN, danABORTED. - Gunakan algoritma backoff eksponensial untuk menunggu dalam jangka waktu yang semakin lama di antara percobaan ulang. Tindakan ini membantu menghindari layanan yang sudah tertekan menjadi lebih tertekan. Misalnya, tunggu 1 detik, lalu 2 detik, lalu 4 detik, dan teruskan hingga jumlah maksimum percobaan ulang atau total waktu tunggu.
- Tambahkan sejumlah kecil "jitter" acak ke penundaan mundur untuk mencegah masalah "kawanan guntur" saat banyak klien mencoba lagi secara bersamaan.
- Coba lagi hanya untuk error server sementara seperti
- Catat secara menyeluruh
Catat respons error lengkap, termasuk semua payload detail standar, terutama ID permintaan. Informasi ini penting untuk men-debug dan melaporkan masalah ke dukungan Google jika diperlukan.
- Memberikan masukan pengguna
Berdasarkan kode dan pesan dalam payload detail standar, berikan masukan yang jelas dan bermanfaat kepada pengguna aplikasi Anda. Misalnya, alih-alih hanya "Terjadi kesalahan", Anda dapat mengatakan "ID transaksi tidak ada" atau "ID akun tujuan tidak ditemukan".
Dengan mengikuti panduan ini, Anda dapat mendiagnosis dan menangani error yang ditampilkan oleh Data Manager API secara efektif, sehingga menghasilkan aplikasi yang lebih stabil dan mudah digunakan.