يوضّح هذا الدليل كيف تعالج واجهة برمجة التطبيقات Data Manager API الأخطاء وتُبلغ عنها. إنّ فهم بنية أخطاء واجهة برمجة التطبيقات ومعناها أمر بالغ الأهمية لإنشاء تطبيقات قوية يمكنها التعامل مع المشاكل بسلاسة، بدءًا من الإدخال غير الصالح إلى عدم توفّر الخدمة مؤقتًا.
تتّبع Data Manager API نموذج الأخطاء العادي في Google API، والذي يستند إلى رموز الحالة في gRPC. يتضمّن كل ردّ من واجهة برمجة التطبيقات يؤدي إلى حدوث خطأ كائن Status يتضمّن ما يلي:
- رمز خطأ رقمي
- رسالة خطأ
- تفاصيل إضافية اختيارية عن الخطأ
رموز الخطأ المتعلقة بالعناوين الأساسية
تستخدِم Data Manager API مجموعة من رموز الخطأ الأساسية التي يحدّدها gRPC وHTTP. تقدّم هذه الرموز إشارة عالية المستوى إلى نوع الخطأ. يجب دائمًا التحقّق من هذا الرمز أولاً لفهم الطبيعة الأساسية للمشكلة.
لمزيد من التفاصيل حول هذه الرموز، يُرجى الاطّلاع على دليل تصميم واجهة برمجة التطبيقات - رموز الخطأ.
معالجة الأخطاء
اتّبِع الخطوات التالية عند تعذُّر تنفيذ طلب:
اطّلِع على رمز الخطأ لمعرفة نوع الخطأ.
- إذا كنت تستخدم gRPC، سيكون رمز الخطأ في الحقل
codeمنStatus. إذا كنت تستخدم مكتبة برامج، قد تعرض نوعًا معيّنًا من الاستثناءات يتوافق مع رمز الخطأ. على سبيل المثال، تعرض مكتبة برامج Javacom.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وQuotaFailureوRetryInfoمفيدة لرموز الخطأ المحدّدة التالية:- إذا كان رمز الحالة هو
INVALID_ARGUMENT، راجِع حمولةBadRequestللحصول على معلومات حول الحقول التي تسبّبت في حدوث الخطأ. - إذا كان رمز الحالة هو
RESOURCE_EXHAUSTED، راجِع حمولاتQuotaFailureوRetryInfoللحصول على معلومات حول الحصة واقتراح بشأن تأخير إعادة المحاولة.
- يحتوي
حمولة التفاصيل العادية
في ما يلي حمولات التفاصيل العادية الأكثر شيوعًا لواجهة برمجة التطبيقات "إدارة بيانات Google":
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 ليس رقمًا. تعرض القيمة field destinations[0].login_account.account_id
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"
}
]
}
]
}
}
QuotaFailure وRetryInfo
تحقَّق من حمولات QuotaFailure وRetryInfo عند تعذُّر تنفيذ طلب
مع ظهور الخطأ RESOURCE_EXHAUSTED (رمز حالة HTTP 429).
تشير الرسالة QuotaFailure إلى أنّه تم استنفاد أحد الموارد (على سبيل المثال، تجاوزت الحصة المخصّصة لك)، أو أنّ النظام مثقل. افحص قائمة violations لتحديد الحصص التي تم تجاوزها.
قد يتضمّن الخطأ أيضًا الرسالة RetryInfo، التي تشير إلى retry_delay مقترَحة لإعادة محاولة الطلب.
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.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 و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.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"
}
]
},
...
]
}
}
تفاصيل الخطأ المتعلّقة بإذن الوصول
إذا كنت تستخدم إحدى مكتبات العملاء، استخدِم طرق المساعدة للحصول على حمولات تفاصيل الإعلانات العادية.
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.
...
}
أفضل الممارسات لمعالجة الأخطاء
لإنشاء تطبيقات مرنة، اتّبِع أفضل الممارسات التالية.
- فحص تفاصيل الخطأ
- ابحث دائمًا عن أحد حمولة التفاصيل القياسية مثل
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 والتعامل معها بفعالية، ما يؤدي إلى إنشاء تطبيقات أكثر استقرارًا وسهولة في الاستخدام.