الردود على الخطأ

الردود العادية على الأخطاء

في حال نجاح طلب واجهة برمجة تطبيقات الإدارة، تعرض واجهة برمجة التطبيقات رمز حالة 200. إذا حدث خطأ في الطلب، ستعرض واجهة برمجة التطبيقات رمز حالة HTTP وحالتها وسببها في الرد استنادًا إلى نوع الخطأ. بالإضافة إلى ذلك، يحتوي نص الاستجابة على وصف تفصيلي لسبب الخطأ. في ما يلي مثال على استجابة خطأ:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "invalidParameter",
    "message": "Invalid value '-1' for max-results. Value must be within the range: [1, 1000]",
    "locationType": "parameter",
    "location": "max-results"
   }
  ],
  "code": 400,
  "message": "Invalid value '-1' for max-results. Value must be within the range: [1, 1000]"
 }
}

جدول الأخطاء

الرمز السبب الوصف الإجراء المقترَح
400 invalidParameter تشير هذه القيمة إلى أن معلمة الطلب لها قيمة غير صالحة. يقدّم الحقلان locationType وlocation في استجابة الخطأ معلومات حول القيمة غير الصالحة. لا تُعِد المحاولة بدون حلّ المشكلة. وعليك تقديم قيمة صالحة للمعلمة المحدّدة في استجابة الخطأ.
400 badRequest تشير إلى أن طلب البحث غير صالح. على سبيل المثال، لم يكن رقم تعريف أحد الوالدَين مفقودًا أو أنّ مجموعة السمات أو المقاييس المطلوبة غير صالحة. لا تُعِد المحاولة بدون حلّ المشكلة. وعليك إجراء تغييرات على طلب البيانات من واجهة برمجة التطبيقات لكي تعمل.
401 invalidCredentials يشير إلى أن الرمز المميز للمصادقة غير صالح أو منتهي الصلاحية. لا تُعِد المحاولة بدون حلّ المشكلة. يجب الحصول على رمز مصادقة جديد.
403 insufficientPermissions يشير إلى أن المستخدم لا يمتلك الأذونات الكافية للكيان المحدد في طلب البحث. لا تُعِد المحاولة بدون حلّ المشكلة. يجب الحصول على أذونات كافية لتنفيذ العملية على الكيان المحدّد.
403 dailyLimitExceeded تشير إلى أن المستخدم قد تجاوز الحصة اليومية (إما لكل مشروع أو لكل ملف شخصي). لا تُعِد المحاولة بدون حلّ المشكلة. لقد استنفدت حصتك اليومية. يُرجى الاطّلاع على حدود واجهة برمجة التطبيقات والحصص.
403 userRateLimitExceeded يشير إلى أنّه تم تجاوز الحدّ طلبات البحث لكل 100 ثانية لكل مستخدم. تكون القيمة التلقائية المحدَّدة في وحدة تحكّم Google API هي 100 طلب لكل 100 ثانية لكل مستخدم. ويمكنك زيادة هذا الحد في وحدة تحكم واجهة برمجة تطبيقات Google إلى 1000 كحد أقصى. يُرجى إعادة المحاولة باستخدام التراجع الأسي. وعليك إبطاء معدّل إرسال الطلبات.
403 rateLimitExceeded تشير إلى أنّ المشروع قد تجاوز حدود طلبات البحث لكل 100 ثانية. يُرجى إعادة المحاولة باستخدام التراجع الأسي. وعليك إبطاء معدّل إرسال الطلبات.
403 quotaExceeded يشير إلى أنه تم الوصول إلى 10 طلبات متزامنة لكل ملف شخصي في واجهة برمجة التطبيقات الأساسية لإعداد التقارير. يُرجى إعادة المحاولة باستخدام التراجع الأسي. وعليك الانتظار حتى يكتمل طلب قيد التقدم واحد على الأقل لهذا الملف الشخصي.
500 internalServerError حدث خطأ داخلي غير متوقع في الخادم. لا تحاول طلب البحث هذا أكثر من مرة.
503 backendError عرض الخادم خطأً. لا تحاول طلب البحث هذا أكثر من مرة.

معالجة 500 أو 503 رد

وقد يؤدي خطأ 500 أو 503 إلى تحميل شديد أو تحميل طلبات أكثر تعقيدًا. بالنسبة إلى الطلبات الأكبر حجمًا، ننصحك بطلب البيانات لفترة زمنية أقصر. وننصحك أيضًا بتنفيذ خوارزمية الرقود الأسي. يمكن أن يعتمد معدل تكرار هذه الأخطاء على الملف الشخصي ومقدار بيانات إعداد التقارير المرتبطة بذلك الملف الشخصي، ولا يؤدي طلب البحث الذي يتسبب في حدوث خطأ 500 أو 503 لملف شخصي واحد بالضرورة إلى حدوث خطأ في طلب البحث نفسه باستخدام ملف شخصي مختلف.

تنفيذ عملية التراجع الأسي

التراجُع الأسي هو عملية تعيد البرنامج محاولة إجراء طلب دوري بشكل دوري على مدار فترة زمنية متزايدة. وهذه إحدى استراتيجيات معالجة الأخطاء العادية لتطبيقات الشبكة. تم تصميم واجهة برمجة التطبيقات Management API مع وضع توقع أن العملاء الذين يعيدون تنفيذ الطلبات التي تعذّر تنفيذها، ينفّذون ذلك باستخدام خوارزمية الرقود الأسي. بالإضافة إلى استخدام ""required;quot"، يؤدي استخدام خوارزمية الرقود الأسي إلى زيادة كفاءة استخدام معدّل نقل البيانات، وتقليل عدد الطلبات المطلوبة للحصول على استجابة ناجحة، وزيادة سرعة معالجة الطلبات في البيئات المتزامنة.

في ما يلي خطوات تنفيذ خوارزمية الرقود الأسي البسيط.

  1. تقديم طلب إلى واجهة برمجة التطبيقات
  2. تلقّي استجابة خطأ تتضمّن رمز خطأ يمكن إعادة المحاولة
  3. الانتظار لمدة ثانية واحدة + random_number_milliseconds ثانية
  4. إعادة محاولة الطلب
  5. تلقّي استجابة خطأ تتضمّن رمز خطأ يمكن إعادة المحاولة
  6. الانتظار لمدة ثانيتين + random_number_milliseconds ثانية
  7. إعادة محاولة الطلب
  8. تلقّي استجابة خطأ تتضمّن رمز خطأ يمكن إعادة المحاولة
  9. الانتظار لمدة 4 ثوانٍ + random_number_milliseconds ثانية
  10. إعادة محاولة الطلب
  11. تلقّي استجابة خطأ تتضمّن رمز خطأ يمكن إعادة المحاولة
  12. الانتظار لمدة 8 ثوانٍ + random_number_milliseconds ثانية
  13. إعادة محاولة الطلب
  14. تلقّي استجابة خطأ تتضمّن رمز خطأ يمكن إعادة المحاولة
  15. الانتظار لمدة 16 ثانية + random_number_milliseconds ثانية
  16. إعادة محاولة الطلب
  17. إذا استمر ظهور الخطأ، أوقِف الخطأ وسجِّله.

في العملية الواردة أعلاه، يمثّل random_number_milliseconds عددًا عشوائيًا من الملي ثانية يقل عن 1, 000 أو يساويه. يُعدّ ذلك ضروريًا لتجنّب أخطاء خطأ معيّنة في بعض عمليات التنفيذ المتزامنة. يجب إعادة تحديد random_number_milliseconds بعد كل انتظار.

ملاحظة: تكون مدة الانتظار دائمًا (2 ^ n) + random_number_milliseconds، حيث يكون n عددًا صحيحًا أحاديًا يزيد في البداية بالقيمة 0. وتتم زيادة n بمقدار 1 لكل تكرار (كل طلب).

يتم ضبط الخوارزمية على الانتهاء عندما يكون n 5. تم وضع هذا الحدّ الأقصى لمنع العملاء من إعادة المحاولة بلا حدود، وقد ينتج عن ذلك تأخير إجمالي يستغرق حوالي 32 ثانية قبل أن يتم اعتبار الطلب "&" خطأً غير قابل للاسترداد.

يمثّل رمز Python التالي تنفيذًا لعملية الاسترداد أعلاه من الأخطاء التي تحدث بطريقة تُسمّى makeRequest.

import random
import time
from apiclient.errors import HttpError

def makeRequestWithExponentialBackoff(analytics):
  """Wrapper to request Google Analytics data with exponential backoff.

  The makeRequest method accepts the analytics service object, makes API
  requests and returns the response. If any error occurs, the makeRequest
  method is retried using exponential backoff.

  Args:
    analytics: The analytics service object

  Returns:
    The API response from the makeRequest method.
  """
  for n in range(0, 5):
    try:
      return makeRequest(analytics)

    except HttpError, error:
      if error.resp.reason in ['userRateLimitExceeded', 'quotaExceeded',
                               'internalServerError', 'backendError']:
        time.sleep((2 ** n) + random.random())
      else:
        break

  print "There has been an error, the request never succeeded."