يشرح هذا الدليل كيفية معالجة الأخطاء في Data Manager API وكيفية الإبلاغ عنها. إنّ فهم بنية أخطاء واجهة برمجة التطبيقات ومعناها أمر بالغ الأهمية لإنشاء تطبيقات قوية يمكنها معالجة المشاكل بشكل سليم، بدءًا من الإدخال غير الصالح وصولاً إلى عدم توفّر الخدمة مؤقتًا.
تتّبع Data Manager API نموذج أخطاء Google API العادي، الذي يستند
إلى رموز حالة gRPC. يتضمّن كل ردّ من واجهة برمجة التطبيقات يؤدي إلى حدوث خطأ كائن Status يتضمّن ما يلي:
- رمز خطأ رقمي
- رسالة خطأ
- تفاصيل إضافية اختيارية عن الخطأ
رموز الخطأ الأساسية
تستخدم Data Manager API مجموعة من رموز الخطأ الأساسية التي تحدّدها gRPC وHTTP. تقدّم هذه الرموز مؤشرًا عالي المستوى على نوع الخطأ. ننصحك بالتحقّق من هذا الرمز أولاً لفهم الطبيعة الأساسية للمشكلة.
لمزيد من التفاصيل حول هذه الرموز، يُرجى الاطّلاع على دليل تصميم واجهة برمجة التطبيقات - رموز الخطأ.
معالجة الأخطاء
اتّبِع الخطوات التالية عندما يتعذّر تنفيذ طلب:
تحقَّق من رمز الخطأ للعثور على نوع الخطأ.
- إذا كنت تستخدم gRPC، يكون رمز الخطأ في الحقل
codeمنStatus. إذا كنت تستخدم مكتبة عميل، قد تعرض نوعًا معيّنًا من الاستثناءات يتطابق مع رمز الخطأ. على سبيل المثال، تعرض مكتبة العميل للغة Java استثناءً من النوعcom.google.api.gax.rpc.InvalidArgumentExceptionإذا كان رمز الخطأ هوINVALID_ARGUMENT. - إذا كنت تستخدم REST، يكون رمز الخطأ في ردّ الخطأ ضِمن
error.status، وتكون حالة HTTP المقابلة ضِمنerror.code.
- إذا كنت تستخدم gRPC، يكون رمز الخطأ في الحقل
تحقَّق من حمولة التفاصيل العادية لرمز الخطأ. إنّ حمولات التفاصيل العادية هي مجموعة من الرسائل للأخطاء الواردة من Google APIs. تقدّم لك تفاصيل الخطأ بطريقة منظَّمة ومتّسقة. قد يتضمّن كل خطأ من Data Manager API رسائل حمولة تفاصيل عادية متعدّدة. تحتوي مكتبات عميل Data Manager API على طرق مساعِدة للحصول على حمولات التفاصيل العادية من الخطأ.
بغض النظر عن رمز الخطأ، ننصحك بالبحث عن حمولات
ErrorInfoوRequestInfoوHelpو وLocalizedMessageوتسجيلها.- تحتوي
ErrorInfoعلى معلومات قد لا تكون متوفّرة في حمولات أخرى. RequestInfoيحتوي على رقم تعريف الطلب، وهو مفيد إذا كنت بحاجة إلى التواصل مع فريق الدعم.- تحتوي
HelpوLocalizedMessageعلى روابط وتفاصيل أخرى لمساعدتك في معالجة الخطأ.
بالإضافة إلى ذلك، تكون حمولة
BadRequestمفيدة للأخطاء من النوعINVALID_ARGUMENTلأنّها تقدّم معلومات عن الحقول التي تسبّبت في حدوث الخطأ.- تحتوي
حمولة التفاصيل العادية
في ما يلي حمولات التفاصيل العادية الأكثر شيوعًا في Data Manager API:
BadRequest
ابحث عن حمولة BadRequest عندما يتعذّر تنفيذ طلب بسبب
INVALID_ARGUMENT (رمز حالة HTTP هو 400).
توضّح رسالة BadRequest أنّ الطلب كان يحتوي على حقول تتضمّن قيمًا غير صالحة أو كان يفتقد قيمة لحقل مطلوب. تحقَّق من قائمة field_violations في BadRequest للعثور على الحقول التي تحتوي على أخطاء. يحتوي كل إدخال من field_violations على معلومات لمساعدتك في إصلاح الخطأ:
fieldموقع الحقل في الطلب، باستخدام بنية مسار camel case.
إذا كان المسار يشير إلى عنصر في قائمة (حقل
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 الذي يحدّد طلب بيانات من واجهة برمجة التطبيقات بشكل فريد.
{
"@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"
}
},
...
]
}
}
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...
// Log the details in the 'Metadata' map...
foreach (
KeyValuePair<String, String> metadataEntry in errorInfo.Metadata
)
{
// Log the metadataEntry.Key and metadataEntry.Value...
}
}
else
{
// ...
}
}
}
جافا
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...
}
...
}
أفضل الممارسات لمعالجة الأخطاء
لإنشاء تطبيقات مرنة، اتّبِع أفضل الممارسات التالية.
- فحص تفاصيل الخطأ
- ابحث دائمًا عن إحدى حمولات التفاصيل العادية، مثل
BadRequest. تحتوي كل حمولة تفاصيل عادية على معلومات لمساعدتك في فهم سبب الخطأ. - التمييز بين أخطاء العميل وأخطاء الخادم
حدِّد ما إذا كان الخطأ ناتجًا عن مشكلة في عملية التنفيذ (العميل) أو مشكلة في واجهة برمجة التطبيقات (الخادم).
- أخطاء العميل: رموز مثل
INVALID_ARGUMENTوNOT_FOUNDوPERMISSION_DENIEDوFAILED_PRECONDITIONوUNAUTHENTICATEDتتطلّب هذه الرموز إجراء تغييرات على الطلب أو حالة تطبيقك أو بيانات اعتماده. لا تعِد محاولة تنفيذ الطلب بدون معالجة المشكلة. - أخطاء الخادم: رموز مثل
UNAVAILABLEوINTERNALوDEADLINE_EXCEEDEDوUNKNOWNتشير هذه الرموز إلى مشكلة مؤقتة في خدمة واجهة برمجة التطبيقات.
- أخطاء العميل: رموز مثل
- تنفيذ استراتيجية إعادة المحاولة
حدِّد ما إذا كان يمكن إعادة محاولة تنفيذ الطلب، واستخدِم استراتيجية إعادة المحاولة.
- أعِد المحاولة فقط لأخطاء الخادم المؤقتة، مثل
UNAVAILABLEوDEADLINE_EXCEEDEDوINTERNALوUNKNOWNوABORTED. - استخدِم خوارزمية الرقود الأسي الثنائي للانتظار لفترات متزايدة بين عمليات إعادة المحاولة. يساعد ذلك في تجنُّب إرهاق خدمة متأثرة أصلاً. على سبيل المثال، انتظِر ثانية واحدة، ثم ثانيتَين، ثم 4 ثوانٍ، واستمرّ في ذلك حتى الوصول إلى الحد الأقصى لعدد عمليات إعادة المحاولة أو إجمالي وقت الانتظار.
- أضِف مقدارًا صغيرًا عشوائيًا من "التذبذب" إلى فترات الرقود لتجنُّب مشكلة "القطيع الصاخب" حيث يعيد العديد من العملاء المحاولة في الوقت نفسه.
- أعِد المحاولة فقط لأخطاء الخادم المؤقتة، مثل
- التسجيل بدقة
سجِّل ردّ الخطأ الكامل، بما في ذلك جميع حمولات التفاصيل العادية، وخاصةً رقم تعريف الطلب. هذه المعلومات ضرورية لتحديد المشاكل وحلّها وإبلاغ فريق دعم Google بها إذا لزم الأمر.
- تقديم ملاحظات للمستخدمين
استنادًا إلى الرموز والرسائل في حمولات التفاصيل العادية، قدِّم ملاحظات واضحة ومفيدة لمستخدمي تطبيقك. على سبيل المثال، بدلاً من مجرد "حدث خطأ"، يمكنك كتابة "لم يتم العثور على رقم تعريف المعاملة" أو "لم يتم العثور على رقم تعريف حساب الوجهة".
باتّباع هذه الإرشادات، يمكنك تشخيص الأخطاء التي تعرضها Data Manager API ومعالجتها بفعالية، ما يؤدي إلى إنشاء تطبيقات أكثر استقرارًا وسهولة في الاستخدام.