تنفيذ معالجة الأخطاء عند استخدام واجهة برمجة تطبيقات الجلب

توضح هذه المقالة بعض أساليب معالجة الأخطاء عند التعامل مع Fetch API. تتيح لك واجهة برمجة تطبيقات الجلب تقديم طلب إلى مورد شبكة بعيد. عند إجراء اتصال بشبكة بعيدة، تصبح صفحة الويب عرضة لمجموعة متنوعة من أخطاء الشبكة المحتملة.

تصف الأقسام التالية الأخطاء المحتملة وتصف كيفية كتابة تعليمات برمجية توفر مستوى معقولاً من الوظائف يتسم بالمرونة في مواجهة الأخطاء وحالات الشبكة غير المتوقعة. يحافظ الرمز المرن على رضا المستخدمين ويحافظ على مستوى عادي من الخدمة لموقعك الإلكتروني.

توقُّع الأخطاء المحتملة في الشبكة

يصف هذا القسم سيناريو ينشئ فيه المستخدم فيديو جديدًا باسم "My Travels.mp4" ثم يحاول تحميل الفيديو إلى موقع إلكتروني لمشاركة الفيديوهات.

عند استخدام أداة "جلب"، من السهل أن تأخذ في الاعتبار المسار الصحيح الذي يؤدي فيه المستخدم إلى تحميل الفيديو بنجاح. ومع ذلك، هناك مسارات أخرى ليست سلسة، ولكن يجب على مطوري الويب التخطيط لها. وقد تحدث هذه المسارات (غير المرضية) بسبب خطأ من المستخدم أو بسبب ظروف بيئية غير متوقعة أو بسبب خطأ في الموقع الإلكتروني لمشاركة الفيديوهات.

أمثلة على أخطاء المستخدم

  • يحمّل المستخدم ملف صورة (مثل JPEG) بدلاً من ملف فيديو.
  • يبدأ المستخدم في تحميل ملف فيديو خاطئ. بعد ذلك، خلال مرحلة التحميل، يحدد المستخدم ملف الفيديو الصحيح للتحميل.
  • نقر المستخدم بطريق الخطأ على "إلغاء التحميل" أثناء تحميل الفيديو.

أمثلة على التغيّرات البيئية

  • انقطع الاتصال بالإنترنت أثناء تحميل الفيديو.
  • تتم إعادة تشغيل المتصفح أثناء تحميل الفيديو.
  • تتم إعادة تشغيل خوادم موقع الويب المخصص لمشاركة الفيديو أثناء تحميل الفيديو.

أمثلة على الأخطاء في موقع الويب المخصص لمشاركة الفيديوهات

  • لا يمكن لموقع ويب مشاركة الفيديو التعامل مع اسم ملف يحتوي على مسافة. وبدلاً من "My Travels.mp4"، من المتوقّع توفّر اسم مثل "My_Travels.mp4" أو "MyTravels.mp4".
  • لا يمكن لموقع ويب مشاركة الفيديو تحميل فيديو يتجاوز الحد الأقصى المسموح به لحجم الملف.
  • لا يدعم موقع مشاركة الفيديو برنامج ترميز الفيديو في الفيديو الذي تم تحميله.

هذه الأمثلة يمكن أن تحدث بالفعل في العالم الحقيقي. ربما تكون قد صادفت مثل هذه الأمثلة في الماضي! لنختر مثالاً واحدًا من كل فئة من الفئات السابقة، ونناقش النقاط التالية:

  • ما السلوك الافتراضي إذا لم تتمكن خدمة مشاركة الفيديو من التعامل مع المثال المقدم؟
  • ماذا يتوقع المستخدم أن يحدث في المثال؟
  • كيف يمكننا تحسين هذه العملية؟
الإجراء يبدأ المستخدم في تحميل ملف فيديو خاطئ. بعد ذلك، خلال مرحلة التحميل، يحدد المستخدم ملف الفيديو الصحيح للتحميل.
ما يحدث بشكل تلقائي يستمر تحميل الملف الأصلي في الخلفية بينما يتم تحميل الملف الجديد في الوقت نفسه.
ما يتوقعه المستخدم يتوقّع المستخدم أن يتوقف التحميل الأصلي حتى لا يتم إهدار أي معدل نقل بيانات إضافي للإنترنت.
ما الذي يمكن تحسينه تلغي لغة JavaScript طلب استرجاع الملف الأصلي قبل بدء تحميل الملف الجديد.
الإجراء ينقطع المستخدم الاتصال بالإنترنت قبل تحميل الفيديو.
ما يحدث بشكل تلقائي يبدو أنّ شريط تقدّم التحميل متوقف عند نسبة 50%. في النهاية، تواجه واجهة برمجة تطبيقات الجلب مهلة ويتم تجاهل البيانات التي تم تحميلها. عند عودة الاتصال بالإنترنت، على المستخدم إعادة تحميل الملف.
ما يتوقعه المستخدم يتوقع المستخدم أن يتم إشعاره عندما يتعذر تحميل الملف، كما يتوقع استئناف التحميل تلقائيًا بنسبة 50% عند معاودة الاتصال بالإنترنت.
ما الذي يمكن تحسينه تُعلِم صفحة التحميل المستخدم بمشاكل في الاتصال بالإنترنت، وتطمئن المستخدم بأنّه سيتم استئناف التحميل عند استئناف الاتصال بالإنترنت.
الإجراء لا يمكن لموقع ويب مشاركة الفيديو التعامل مع اسم ملف يحتوي على مسافة. بدلاً من "My Travels.mp4"، سيتوقع استخدام أسماء مثل "My_Travels.mp4" أو "MyTravels.mp4".
ما يحدث بشكل تلقائي يجب أن ينتظر المستخدم حتى ينتهي التحميل بالكامل. بعد تحميل الملف، وسيظهر "100%" في شريط التقدّم، يعرض شريط التقدّم الرسالة التالية: "يُرجى إعادة المحاولة".
ما يتوقعه المستخدم يتوقع المستخدم أن يتم إخباره بالقيود المفروضة على اسم الملف قبل بدء التحميل، أو على الأقل خلال الثانية الأولى من التحميل.
ما الذي يمكن تحسينه ومن الناحية المثالية، تتيح خدمة مشاركة الفيديو أسماء الملفات التي تحتوي على مسافات. ويمكنك بدلاً من ذلك إعلام المستخدم بقيود اسم الملف قبل بدء التحميل. أو، يجب أن ترفض خدمة مشاركة الفيديو التحميل مع عرض رسالة خطأ مفصلة.

التعامل مع الأخطاء باستخدام Fetch API

تجدر الإشارة إلى أنّ أمثلة الرموز التالية تستخدم await ذات المستوى الأعلى (إتاحة المتصفِّح) لأن هذه الميزة يمكنها تبسيط الرمز.

عندما تعرض Fetch API الأخطاء

يستخدم هذا المثال عبارة حظر try/catch لرصد أي أخطاء تظهر ضمن مجموعة try. على سبيل المثال، إذا لم تتمكن واجهة برمجة تطبيقات الجلب من جلب المورد المحدد، فسيتم عرض خطأ. احرص على تقديم تجربة مستخدم هادفة داخل مجموعة catch مثل هذه. إذا ظهر للمستخدم مؤشر سريان العمل، وهو واجهة مستخدم شائعة تمثّل مستوى تقدّمًا معيّنًا، يمكنك اتّخاذ الإجراءات التالية ضمن مجموعة catch:

  1. أزِل المؤشر الدوّار من الصفحة.
  2. يجب تقديم رسائل مفيدة تشرح المشكلة التي حدثت والخيارات التي يمكن أن يتخذها المستخدم.
  3. استنادًا إلى الخيارات المتاحة، اعرض زر "إعادة المحاولة" للمستخدم.
  4. خلف الكواليس، أرسل تفاصيل الخطأ إلى خدمة تتبع الأخطاء لديك أو إلى الخلفية. ويسجّل هذا الإجراء الخطأ حتى يمكن تشخيصه في مرحلة لاحقة.
try {
  const response = await fetch('https://website');
} catch (error) {
  // TypeError: Failed to fetch
  console.log('There was an error', error);
}

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

عندما يمثل رمز حالة الشبكة خطأ

يقدّم مثال الرمز هذا طلبًا لخدمة اختبار HTTP تستجيب دائمًا برمز حالة HTTP 429 Too Many Requests. من المثير للاهتمام أنّ الردّ لم يصل إلى مجموعة "catch". لا تعرض الحالة 404، بين رموز الحالة الأخرى، خطأ في الشبكة، بل تحل محلها بشكل طبيعي.

للتحقق من نجاح رمز حالة HTTP، يمكنك استخدام أي من الخيارات التالية:

  • استخدِم السمة Response.ok لتحديد ما إذا كان رمز الحالة يقع في النطاق من 200 إلى 299.
  • استخدِم السمة Response.status لتحديد ما إذا كانت الاستجابة ناجحة.
  • استخدِم أي بيانات وصفية أخرى، مثل Response.headers، لتقييم ما إذا كان الردّ ناجحًا.
let response;

try {
  response = await fetch('https://httpbin.org/status/429');
} catch (error) {
  console.log('There was an error', error);
}

// Uses the 'optional chaining' operator
if (response?.ok) {
  console.log('Use the response here!');
} else {
  console.log(`HTTP Response Code: ${response?.status}`)
}

تتمثل أفضل الممارسات في العمل مع الأشخاص في مؤسستك وفريقك لفهم رموز استجابة HTTP المحتملة. في بعض الأحيان، يمكن لمطوّري الواجهة الخلفية وعمليات المطوّرين ومهندسي الخدمة تقديم معلومات فريدة حول الحالات الهامشية المحتملة التي قد لا تتوقعها.

عند حدوث خطأ في تحليل استجابة الشبكة

يوضح مثال الرمز هذا نوعًا آخر من الخطأ الذي يمكن أن ينشأ مع تحليل نص الاستجابة. توفّر واجهة Response طرقًا ملائمة لتحليل أنواع مختلفة من البيانات، مثل النص أو JSON. في التعليمة البرمجية التالية، يتم إجراء طلب شبكة إلى خدمة اختبار HTTP تعرض سلسلة HTML كنص استجابة. ومع ذلك، هناك محاولة لتحليل نص الاستجابة بتنسيق JSON، ما يؤدي إلى ظهور خطأ.

let json;

try {
  const response = await fetch('https://httpbin.org/html');
  json = await response.json();
} catch (error) {
  if (error instanceof SyntaxError) {
    // Unexpected token < in JSON
    console.log('There was a SyntaxError', error);
  } else {
    console.log('There was an error', error);
  }
}

if (json) {
  console.log('Use the JSON here!', json);
}

يجب تحضير الرمز بحيث يستقبل مجموعة متنوعة من تنسيقات الردود، والتأكّد من أنّ استجابة غير متوقعة لا تؤدي إلى تقسيم صفحة الويب لدى المستخدم.

ضع في اعتبارك السيناريو التالي: لديك مورد بعيد يعرض استجابة JSON صالحة، وتم تحليله بنجاح باستخدام طريقة Response.json(). وقد يحدث ذلك لانقطاع الخدمة. مرة واحدة، يتم عرض 500 Internal Server Error. إذا لم يتم استخدام أساليب معالجة الأخطاء المناسبة أثناء تحليل JSON، قد يؤدي ذلك إلى تقسيم الصفحة للمستخدم بسبب ظهور خطأ لم تتم معالجته.

الحالات التي يجب فيها إلغاء طلب الشبكة قبل اكتماله

يستخدم مثال الرمز هذا AbortController لإلغاء طلب أثناء الرحلة الجوية. الطلب أثناء الطيران هو طلب شبكة قد بدأ ولكن لم يكتمل.

قد تختلف السيناريوهات التي قد تحتاج فيها إلى إلغاء الطلب أثناء الرحلة الجوية، ولكن ذلك يعتمد بشكل أساسي على حالة الاستخدام والبيئة. يوضّح الرمز التالي كيفية تمرير AbortSignal إلى Fetch API. يتم إرفاق AbortSignal بـ AbortController، بينما يتضمّن AbortController طريقة abort()، للإشارة إلى المتصفِّح أنّه يجب إلغاء طلب الشبكة.

const controller = new AbortController();
const signal = controller.signal;

// Cancel the fetch request in 500ms
setTimeout(() => controller.abort(), 500);

try {
  const url = 'https://httpbin.org/delay/1';
  const response = await fetch(url, { signal });
  console.log(response);
} catch (error) {
  // DOMException: The user aborted a request.
  console.log('Error: ', error)
}

الخلاصة

يتمثل أحد جوانب التعامل مع الأخطاء في تحديد الأجزاء المختلفة التي يمكن أن تخطئ. لكل سيناريو، تأكد من وجود إجراء احتياطي مناسب للمستخدم. فيما يتعلق بطلب الاسترجاع، اسأل نفسك أسئلة مثل:

  • ماذا يحدث في حالة تعطل الخادم المستهدف؟
  • ماذا يحدث إذا تلقت أداة الجلب استجابة غير متوقعة؟
  • ماذا يحدث إذا فشل اتصال المستخدم بالإنترنت؟

اعتمادًا على مدى تعقيد صفحة الويب الخاصة بك، يمكنك أيضًا رسم مخطط انسيابي يصف الوظائف وواجهة المستخدم لسيناريوهات مختلفة.