توضح هذه المقالة بعض أساليب معالجة الأخطاء عند التعامل مع Fetch API. تتيح لك واجهة برمجة تطبيقات الجلب تقديم طلب إلى مورد شبكة بعيد. عند إجراء اتصال بشبكة بعيدة، تصبح صفحة الويب عرضة لمجموعة متنوعة من أخطاء الشبكة المحتملة.
تصف الأقسام التالية الأخطاء المحتملة وتصف كيفية كتابة تعليمات برمجية توفر مستوى معقولاً من الوظائف يتسم بالمرونة في مواجهة الأخطاء وحالات الشبكة غير المتوقعة. يحافظ الرمز المرن على رضا المستخدمين ويحافظ على مستوى عادي من الخدمة لموقعك الإلكتروني.
توقُّع الأخطاء المحتملة في الشبكة
يصف هذا القسم سيناريو ينشئ فيه المستخدم فيديو جديدًا باسم
"My Travels.mp4"
ثم يحاول تحميل الفيديو إلى موقع إلكتروني لمشاركة الفيديوهات.
عند استخدام أداة "جلب"، من السهل أن تأخذ في الاعتبار المسار الصحيح الذي يؤدي فيه المستخدم إلى تحميل الفيديو بنجاح. ومع ذلك، هناك مسارات أخرى ليست سلسة، ولكن يجب على مطوري الويب التخطيط لها. وقد تحدث هذه المسارات (غير المرضية) بسبب خطأ من المستخدم أو بسبب ظروف بيئية غير متوقعة أو بسبب خطأ في الموقع الإلكتروني لمشاركة الفيديوهات.
أمثلة على أخطاء المستخدم
- يحمّل المستخدم ملف صورة (مثل JPEG) بدلاً من ملف فيديو.
- يبدأ المستخدم في تحميل ملف فيديو خاطئ. بعد ذلك، خلال مرحلة التحميل، يحدد المستخدم ملف الفيديو الصحيح للتحميل.
- نقر المستخدم بطريق الخطأ على "إلغاء التحميل" أثناء تحميل الفيديو.
أمثلة على التغيّرات البيئية
- انقطع الاتصال بالإنترنت أثناء تحميل الفيديو.
- تتم إعادة تشغيل المتصفح أثناء تحميل الفيديو.
- تتم إعادة تشغيل خوادم موقع الويب المخصص لمشاركة الفيديو أثناء تحميل الفيديو.
أمثلة على الأخطاء في موقع الويب المخصص لمشاركة الفيديوهات
- لا يمكن لموقع ويب مشاركة الفيديو التعامل مع اسم ملف يحتوي على مسافة. وبدلاً من
"My Travels.mp4"
، من المتوقّع توفّر اسم مثل"My_Travels.mp4"
أو"MyTravels.mp4"
. - لا يمكن لموقع ويب مشاركة الفيديو تحميل فيديو يتجاوز الحد الأقصى المسموح به لحجم الملف.
- لا يدعم موقع مشاركة الفيديو برنامج ترميز الفيديو في الفيديو الذي تم تحميله.
هذه الأمثلة يمكن أن تحدث بالفعل في العالم الحقيقي. ربما تكون قد صادفت مثل هذه الأمثلة في الماضي! لنختر مثالاً واحدًا من كل فئة من الفئات السابقة، ونناقش النقاط التالية:
- ما السلوك الافتراضي إذا لم تتمكن خدمة مشاركة الفيديو من التعامل مع المثال المقدم؟
- ماذا يتوقع المستخدم أن يحدث في المثال؟
- كيف يمكننا تحسين هذه العملية؟
التعامل مع الأخطاء باستخدام Fetch API
تجدر الإشارة إلى أنّ أمثلة الرموز التالية تستخدم await
ذات المستوى الأعلى (إتاحة المتصفِّح) لأن هذه الميزة يمكنها تبسيط الرمز.
عندما تعرض Fetch API الأخطاء
يستخدم هذا المثال عبارة حظر try
/catch
لرصد أي أخطاء تظهر ضمن مجموعة try
. على سبيل المثال، إذا لم تتمكن واجهة برمجة تطبيقات الجلب من جلب المورد المحدد، فسيتم عرض خطأ. احرص على تقديم تجربة مستخدم هادفة داخل مجموعة catch
مثل هذه. إذا ظهر للمستخدم مؤشر سريان العمل، وهو واجهة مستخدم شائعة تمثّل مستوى تقدّمًا معيّنًا، يمكنك اتّخاذ الإجراءات التالية ضمن مجموعة catch
:
- أزِل المؤشر الدوّار من الصفحة.
- يجب تقديم رسائل مفيدة تشرح المشكلة التي حدثت والخيارات التي يمكن أن يتخذها المستخدم.
- استنادًا إلى الخيارات المتاحة، اعرض زر "إعادة المحاولة" للمستخدم.
- خلف الكواليس، أرسل تفاصيل الخطأ إلى خدمة تتبع الأخطاء لديك أو إلى الخلفية. ويسجّل هذا الإجراء الخطأ حتى يمكن تشخيصه في مرحلة لاحقة.
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)
}
الخلاصة
يتمثل أحد جوانب التعامل مع الأخطاء في تحديد الأجزاء المختلفة التي يمكن أن تخطئ. لكل سيناريو، تأكد من وجود إجراء احتياطي مناسب للمستخدم. فيما يتعلق بطلب الاسترجاع، اسأل نفسك أسئلة مثل:
- ماذا يحدث في حالة تعطل الخادم المستهدف؟
- ماذا يحدث إذا تلقت أداة الجلب استجابة غير متوقعة؟
- ماذا يحدث إذا فشل اتصال المستخدم بالإنترنت؟
اعتمادًا على مدى تعقيد صفحة الويب الخاصة بك، يمكنك أيضًا رسم مخطط انسيابي يصف الوظائف وواجهة المستخدم لسيناريوهات مختلفة.