يوضّح هذا الدليل كيفية تعامل واجهة Data Manager API مع الأخطاء وإبلاغها. من المهم فهم بنية أخطاء واجهة برمجة التطبيقات ومعناها لإنشاء تطبيقات قوية يمكنها التعامل مع المشاكل بسلاسة، بدءًا من الإدخال غير الصالح وحتى عدم توفّر الخدمة مؤقتًا.
تتّبع واجهة Data Manager API نموذج الخطأ العادي في Google API، والذي يستند إلى رموز حالة gRPC. يتضمّن كل ردّ من واجهة برمجة التطبيقات يؤدي إلى حدوث خطأ عنصر Status يحتوي على:
- رمز خطأ رقمي
- رسالة خطأ
- تفاصيل إضافية اختيارية عن الخطأ
رموز الخطأ الأساسية
تستخدم واجهة Data Manager API مجموعة من رموز الأخطاء الأساسية التي يحدّدها gRPC وHTTP. وتقدّم هذه الرموز مؤشرًا عامًا على نوع الخطأ. يجب عليك دائمًا التحقق من هذا الرمز أولاً لفهم الطبيعة الأساسية للمشكلة.
لمزيد من التفاصيل حول هذه الرموز، يُرجى الاطّلاع على دليل تصميم واجهة برمجة التطبيقات - رموز الخطأ.
نموذج الفشل السريع
تستخدم واجهة Data Manager API نموذجًا سريعًا للإخفاق. إذا كان الطلب يحتوي على أخطاء هيكلية أو إذا تعذّر التحقّق من صحة أي سجلّ لحقل مطلوب، سيتعذّر تنفيذ الطلب بالكامل ولن تعالج واجهة برمجة التطبيقات أي بيانات في هذا الطلب.
المقارنة مع نموذج الفشل الجزئي
يختلف نموذج الفشل السريع عن نموذج الفشل الجزئي في بعض واجهات برمجة التطبيقات الأخرى من Google، مثل Google Ads API وCampaign Manager 360 API. في نموذج الفشل الجزئي، ينجح الطلب حتى إذا كانت بعض السجلات تحتوي على أخطاء، ويتضمّن الردّ تفاصيل الأخطاء في السجلات التي تعذّر إكمالها.
على الرغم من أنّ نموذج الفشل الجزئي قد يكون مناسبًا، إلا أنّه ينطوي على مخاطر كبيرة لأنّه لا ينبّهك إلى الأخطاء بشكل استباقي، بل عليك التحقّق من الأخطاء في كل ردّ بشكل صريح. يمكن أن يؤدي ذلك إلى إخفاء مشاكل مهمة لأنّ الطلب ينجح حتى إذا رفضت واجهة برمجة التطبيقات العديد من السجلّات في الطلب أو حتى جميعها. إذا كان جزء كبير من السجلات في الطلب يحتوي على أخطاء ولكنك لم تفحص الاستجابة، قد لا تكون على دراية كاملة بالمشاكل واسعة النطاق في بياناتك، ولن تكتشف هذه المشاكل إلا بعد أيام أو أسابيع عندما لا تتوافق النتائج التراكمية مع توقعاتك.
يتجنّب نموذج الفشل السريع هذه المشاكل من خلال تنبيهك إلى المشاكل المتعلّقة ببياناتك أو عملية الدمج على الفور حتى تتمكّن من اتّخاذ الإجراء المناسب.
التحقّق من أخطاء الفشل السريع باستخدام validateOnly
تتيح معظم طلبات الاستيعاب والإزالة استخدام حقل validateOnly. عند ضبط validateOnly على true، تُجري واجهة Data Manager API عمليات التحقّق الأساسية نفسها التي تُجريها لطلب عادي، ولكنّها لا تستوعب أي بيانات أو تزيلها.
- إذا كان الطلب يحتوي على أخطاء، سيتعذّر تنفيذه وستتلقّى ردّ الخطأ نفسه الذي تتلقّاه من طلب عادي.
- إذا اجتاز الطلب عملية التحقّق، يتم تنفيذه بنجاح. يتضمّن الردّ أيّ
fieldWarningsللحقول الاختيارية، تمامًا مثل الطلب العادي.
استخدِم validateOnly لتنفيذ ما يلي:
- اختبِر عملية دمج جديدة أو معدَّلة بدون التأثير في بياناتك المنشورة.
- تأكَّد من أنّ الحلّ يعالج الخطأ قبل إعادة إرسال الطلب.
معالجة الأخطاء
اتّبِع الخطوات التالية في حال تعذّر تنفيذ الطلب:
اطّلِع على رمز الخطأ للعثور على نوع الخطأ.
- إذا كنت تستخدم 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مفيدة لأخطاءINVALID_ARGUMENTلأنّها توفّر معلومات عن الحقول التي تسبّبت في حدوث الخطأ.- يحتوي
تحذيرات بشأن نقل البيانات
تقبل Data Manager API أكبر قدر ممكن من طلبات نقل البيانات. إذا أدرجت بيانات غير مطلوبة، لن تؤدي حالات تعذُّر التحقّق من صحة هذه الحقول إلى تعذُّر تنفيذ الطلب. على سبيل المثال، إذا كانت سلعة في سلة التسوّق لا تتضمّن معرّف منتج التاجر، تعالج واجهة برمجة التطبيقات بقية الطلب وتعرض تحذيرًا.
تتضمّن استجابة نقل البيانات الناجحة (رمز حالة HTTP 200) هذه التحذيرات في قائمة fieldWarnings. كل إدخال هو عنصر FieldWarning يتضمّن الحقول التالية:
fieldموقع الحقل في الطلب، في بنية مسار تنسيق snake case
إذا كان المسار يشير إلى عنصر في قائمة (حقل
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موقع الحقل في الطلب، في بنية مسار تنسيق snake 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"
}
]
}
]
}
}
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"
}
},
...
]
}
}
أخطاء في الحصة والحد الأقصى لمعدّل الاستخدام
عندما يتجاوز الطلب الحدّ الأقصى المسموح به للمشروع، تعرض واجهة برمجة التطبيقات الخطأ 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 عندما يتجاوز الطلب الحدّ الأقصى لطلبات التغيير في الدقيقة:
{
"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
{
// ...
}
}
}
جافا
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();
جافا
// 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. تحتوي كل حمولة تفصيلية عادية على معلومات لمساعدتك في فهم سبب الخطأ. - التمييز بين أخطاء العميل وأخطاء الخادم
حدِّد ما إذا كان الخطأ ناتجًا عن مشكلة في عملية التنفيذ (العميل) أو مشكلة في واجهة برمجة التطبيقات (الخادم).
- أخطاء العميل: رموز مثل
INVALID_ARGUMENTوNOT_FOUNDوPERMISSION_DENIEDوFAILED_PRECONDITIONوUNAUTHENTICATEDوتتطلّب هذه الأخطاء إجراء تغييرات على الطلب أو حالة تطبيقك أو بيانات اعتماده. لا تُعِد محاولة إرسال الطلب بدون حلّ المشكلة. - أخطاء الخادم: رموز مثل
UNAVAILABLEوINTERNALوDEADLINE_EXCEEDEDوUNKNOWNيشير ذلك إلى مشكلة مؤقتة في خدمة واجهة برمجة التطبيقات.
- أخطاء العميل: رموز مثل
- تنفيذ استراتيجية إعادة المحاولة
حدِّد ما إذا كان يمكن إعادة محاولة معالجة الخطأ، واستخدِم استراتيجية لإعادة المحاولة.
يجب إعادة المحاولة فقط في حال حدوث أخطاء مؤقتة في الخادم (مثل
UNAVAILABLEوDEADLINE_EXCEEDEDوINTERNALوUNKNOWNوABORTED) وعند تجاوز حدود معدّل الطلبات في الدقيقة (RESOURCE_EXHAUSTEDمعRATE_LIMIT_EXCEEDED).للاطّلاع على حدود المعدّل، يمكنك فحص
quota_limitفيErrorInfo:إذا كان الحدّ الأقصى في الدقيقة (مثل
IngestionMutateRequestsPerMinutePerProject)، عليك إيقاف الطلبات مؤقتًا و إعادة المحاولة باستخدام خوارزمية الرقود الأسي الثنائي مع التفاوت في الأداء.إذا كان الحدّ الأقصى يوميًا (مثل
IngestionMutateRequestsPerDayPerProject)، لا تُعِد المحاولة على الفور. أوقِف المعالجة مؤقتًا إلى أن تتم إعادة ضبط الحصة اليومية في منتصف الليل بتوقيت المحيط الهادئ.
استخدِم خوارزمية الرقود الأسي الثنائي للانتظار لفترات متزايدة بين المحاولات. يساعد ذلك في تجنُّب إرهاق خدمة مثقلة بالأعباء. على سبيل المثال، الانتظار لمدة ثانية واحدة، ثم ثانيتين، ثم 4 ثوانٍ، مع الاستمرار حتى الوصول إلى الحد الأقصى لعدد المحاولات أو إجمالي وقت الانتظار.
أضِف مقدارًا عشوائيًا صغيرًا من "التشويش" إلى تأخيرات التراجع لمنع مشكلة "الازدحام الشديد" التي يحاول فيها العديد من العملاء إعادة المحاولة في الوقت نفسه.
- تسجيل البيانات بدقة
سجِّل استجابة الخطأ الكاملة، بما في ذلك جميع حمولات التفاصيل العادية، وخاصةً معرّف الطلب. هذه المعلومات ضرورية لتصحيح الأخطاء والإبلاغ عن المشاكل إلى فريق الدعم في Google إذا لزم الأمر.
- تقديم ملاحظات المستخدمين
استنادًا إلى الرموز والرسائل في الحمولات التفصيلية العادية، يمكنك تقديم ملاحظات واضحة ومفيدة لمستخدمي تطبيقك. على سبيل المثال، بدلاً من قول "حدث خطأ" فقط، يمكنك قول "رقم تعريف المعاملة غير متوفّر" أو "لم يتم العثور على رقم تعريف حساب الوجهة".
من خلال اتّباع هذه الإرشادات، يمكنك تشخيص الأخطاء التي تعرضها واجهة برمجة التطبيقات Data Manager API ومعالجتها بفعالية، ما يؤدي إلى إنشاء تطبيقات أكثر استقرارًا وسهولة في الاستخدام.