Bu kılavuzda, Veri Yöneticisi API'sinin hataları nasıl işlediği ve ilettiği açıklanmaktadır. API hatalarının yapısını ve anlamını anlamak, geçersiz girişten geçici hizmet kullanılamazlığına kadar sorunları düzgün bir şekilde ele alabilen sağlam uygulamalar oluşturmak için çok önemlidir.
Veri Yöneticisi API'si, gRPC durum kodlarına dayalı olan standart Google API hata modelini kullanır. Hatayla sonuçlanan her API yanıtında, aşağıdakileri içeren bir Status nesnesi bulunur:
- Sayısal bir hata kodu.
- Hata mesajı
- İsteğe bağlı, ek hata ayrıntıları.
Standartlaştırma hata kodları
Data Manager API, gRPC ve HTTP tarafından tanımlanan bir dizi standart hata kodu kullanır. Bu kodlar, hata türü hakkında üst düzey bir gösterge sağlar. Sorunun temel doğasını anlamak için önce bu kodu kontrol etmeniz gerekir.
Bu kodlar hakkında daha fazla bilgi için API Tasarım Kılavuzu - Hata kodları başlıklı makaleyi inceleyin.
Hataları işleme
Bir istek başarısız olduğunda şu adımları uygulayın:
Hata türünü bulmak için hata kodunu kontrol edin.
- gRPC kullanıyorsanız hata kodu,
Statusöğesinincodealanında yer alır. İstemci kitaplığı kullanıyorsanız hata koduna karşılık gelen belirli bir istisna türü oluşturabilir. Örneğin, Java için istemci kitaplığı, hata koduINVALID_ARGUMENTisecom.google.api.gax.rpc.InvalidArgumentExceptionhatası verir. - REST kullanıyorsanız hata kodu
error.statuskonumundaki hata yanıtında, karşılık gelen HTTP durumu iseerror.codekonumundadır.
- gRPC kullanıyorsanız hata kodu,
Hata kodu için standart ayrıntı yükünü kontrol edin. Standart ayrıntı yükleri, Google API'lerinden gelen hatalarla ilgili bir mesaj grubudur. Hata ayrıntılarını yapılandırılmış ve tutarlı bir şekilde sunar. Veri Yöneticisi API'sindeki her hata birden fazla standart ayrıntı yükü mesajı içerebilir. Data Manager API istemci kitaplıklarında, bir hatadan standart ayrıntı yüklerini almak için yardımcı yöntemler bulunur.
Hata kodu ne olursa olsun
ErrorInfo,RequestInfo,HelpveLocalizedMessageyüklerini kontrol etmenizi ve günlüğe kaydetmenizi öneririz.ErrorInfo, diğer yüklerde bulunmayabilecek bilgiler içeriyor.RequestInfoiçinde, destek ekibiyle iletişime geçmeniz gerekirse yararlı olacak istek kimliği bulunur.HelpveLocalizedMessage, hatayı gidermenize yardımcı olacak bağlantılar ve diğer ayrıntıları içerir.
Ayrıca,
BadRequestyükü, hangi alanların hataya neden olduğu hakkında bilgi sağladığı içinINVALID_ARGUMENThataları için de yararlıdır.
Standart ayrıntı yükleri
Data Manager API için en yaygın standart ayrıntı yükleri şunlardır:
BadRequest
Bir istek INVALID_ARGUMENT (HTTP durum kodu 400) ile başarısız olduğunda BadRequest yükünü kontrol edin.
BadRequest mesajı, isteğin kötü değerlere sahip alanlar içerdiğini veya zorunlu bir alan için değerin eksik olduğunu gösterir. Hangi alanlarda hata olduğunu görmek için field_violations listesini kontrol edin.BadRequest Her field_violations girişinde hatayı düzeltmenize yardımcı olacak bilgiler bulunur:
fieldİstekteki alanın konumu (camel case yolu söz dizimi kullanılarak).
Bir yol, listedeki bir öğeyi (
repeatedalanı) işaret ediyorsa dizini, liste adından sonra köşeli parantez içinde ([...]) gösterilir.Örneğin,
destinations[0].operating_account.account_id,destinationslistesindeki ilk öğeninoperating_accountbölümündekiaccount_id'dir.descriptionDeğerin neden hataya yol açtığına dair açıklama.
reasonINVALID_HEX_ENCODINGveyaINVALID_CURRENCY_CODEgibiErrorReasonenum'u.
BadRequest örnekleri
Aşağıda, BadRequest mesajı içeren bir INVALID_ARGUMENT hatasıyla ilgili örnek bir yanıt verilmiştir. field_violations, hatanın accountId olmayan bir sayı olduğunu gösterir. field değeri destinations[0].login_account.account_id, accountId alan ihlali olan login_account öğesinin destinations listesindeki ilk öğe olduğunu gösterir.
{
"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"
}
]
}
]
}
}
Aşağıda, BadRequest mesajı içeren bir INVALID_ARGUMENT hatasından alınan başka bir örnek yanıt verilmiştir. Bu durumda, field_violations listesinde iki hata gösterilir:
İlk
event, etkinliğin ikinci kullanıcı tanımlayıcısında onaltılık kodlanmamış bir değere sahip.İkinci
event, etkinliğin üçüncü kullanıcı tanımlayıcısında onaltılık olarak kodlanmamış bir değere sahip.
{
"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
Bir istek başarısız olduğunda RequestInfo yükünü kontrol edin. RequestInfo, API isteğinizi benzersiz şekilde tanımlayan request_id içerir.
{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "t-4490c640-dc5d-4c28-91c1-04a1cae0f49f"
}
Günlüğe kaydetme hataları veya destek ekibiyle iletişime geçerken sorunların teşhis edilmesine yardımcı olmak için istek kimliğini eklediğinizden emin olun.
ErrorInfo
Diğer standart ayrıntı yüklerinde yakalanmamış olabilecek ek bilgileri almak için ErrorInfo mesajını kontrol edin. ErrorInfo
Yük, hatayla ilgili bilgilerin yer aldığı bir metadata haritası içerir.
Örneğin, Data Manager API'nin etkin olmadığı bir Google Cloud projesi için kimlik bilgileri kullanıldığında ortaya çıkan PERMISSION_DENIED hatasıyla ilgili ErrorInfo bölümünü burada bulabilirsiniz. ErrorInfo, hata hakkında ek bilgiler sağlar. Örneğin:
- İstekle ilişkili proje,
metadata.consumeraltında. metadata.serviceTitlebölümünde hizmetin adı.- Hizmetin etkinleştirilebileceği URL (
metadata.activationUrlaltında).
{
"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 ve LocalizedMessage
Hatayı anlamanıza ve düzeltmenize yardımcı olacak belgelere ve yerelleştirilmiş hata mesajlarına yönelik bağlantılar almak için Help ve LocalizedMessage yüklerini kontrol edin.
Örneğin, Data Manager API'nin etkinleştirilmediği bir Google Cloud projesinin kimlik bilgilerinin kullanılması nedeniyle oluşan PERMISSION_DENIED hatası için Help ve LocalizedMessage aşağıda verilmiştir. Help yükünde, hizmetin etkinleştirilebileceği URL gösterilir ve LocalizedMessage içinde hatanın açıklaması yer alır.
{
"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"
}
]
},
...
]
}
}
Erişim hatası ayrıntılarına erişme
İstemci kitaplıklarından birini kullanıyorsanız standart ayrıntı yüklerini almak için yardımcı yöntemleri kullanın.
.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...
}
...
}
Hata işleme ile ilgili en iyi uygulamalar
Esnek uygulamalar oluşturmak için aşağıdaki en iyi uygulamaları uygulayın.
- Hata ayrıntılarını inceleme
- Her zaman
BadRequestgibi standart ayrıntı yüklerinden birini arayın. Her standart ayrıntı yükü, hatanın nedenini anlamanıza yardımcı olacak bilgiler içerir. - İstemci hataları ile sunucu hatalarını ayırt etme
Hataya uygulamanızla (istemci) ilgili bir sorunun mu yoksa API ile (sunucu) ilgili bir sorunun mu neden olduğunu belirleyin.
- İstemci hataları:
INVALID_ARGUMENT,NOT_FOUND,PERMISSION_DENIED,FAILED_PRECONDITION,UNAUTHENTICATEDgibi kodlar. Bu tür hatalar, istekte veya uygulamanızın durumunda/kimlik bilgilerinde değişiklik yapılmasını gerektirir. Sorunu çözmeden isteği yeniden göndermeyin. - Sunucu hataları:
UNAVAILABLE,INTERNAL,DEADLINE_EXCEEDED,UNKNOWNgibi kodlar. Bunlar, API hizmetiyle ilgili geçici bir soruna işaret eder.
- İstemci hataları:
- Yeniden deneme stratejisi uygulama
Hatayı yeniden denemenin mümkün olup olmadığını belirleyin ve yeniden deneme stratejisi kullanın.
- Yalnızca
UNAVAILABLE,DEADLINE_EXCEEDED,INTERNAL,UNKNOWNveABORTEDgibi geçici sunucu hataları için yeniden deneyin. - Yeniden denemeler arasında artan sürelerle beklemek için eksponansiyel geri yükleme algoritması kullanın. Bu, zaten stresli olan bir hizmetin aşırı yüklenmesini önlemeye yardımcı olur. Örneğin, önce 1 saniye, sonra 2 saniye, sonra 4 saniye bekleyin ve maksimum yeniden deneme sayısı veya toplam bekleme süresine ulaşana kadar bu şekilde devam edin.
- Birçok istemcinin aynı anda yeniden denediği "gürleyen sürü" sorununu önlemek için geri çekilme gecikmelerine küçük bir rastgele "titreme" miktarı ekleyin.
- Yalnızca
- Kapsamlı günlük kaydı
Tüm standart ayrıntı yükleri, özellikle de istek kimliği dahil olmak üzere hatayla ilgili tam yanıtı günlüğe kaydedin. Bu bilgiler, hata ayıklama ve gerekirse sorunları Google Destek Ekibi'ne bildirme açısından önemlidir.
- Kullanıcı geri bildirimi sağlama
Standart ayrıntı yüklerindeki kodlara ve mesajlara göre uygulamanızın kullanıcılarına net ve faydalı geri bildirimler sağlayın. Örneğin, yalnızca "Bir hata oluştu" demek yerine "İşlem kimliği eksikti" veya "Hedefin hesap kimliği bulunamadı" diyebilirsiniz.
Bu yönergeleri uygulayarak Veri Yöneticisi API'sinin döndürdüğü hataları etkili bir şekilde teşhis edip işleyebilir, böylece daha kararlı ve kullanıcı dostu uygulamalar oluşturabilirsiniz.