هنگام استفاده از Fetch API، مدیریت خطا را اجرا کنید

این مقاله برخی از رویکردهای رسیدگی به خطا را هنگام کار با Fetch API نشان می‌دهد. Fetch API به شما امکان می دهد درخواستی را به یک منبع شبکه راه دور ارسال کنید. هنگامی که یک تماس شبکه از راه دور برقرار می کنید، صفحه وب شما در معرض انواع خطاهای شبکه بالقوه قرار می گیرد.

بخش‌های زیر خطاهای بالقوه را شرح می‌دهند و نحوه نوشتن کدی را توضیح می‌دهند که سطح معقولی از عملکرد را فراهم می‌کند که در برابر خطاها و شرایط غیرمنتظره شبکه مقاوم باشد. کد انعطاف پذیر کاربران شما را راضی نگه می دارد و سطح استاندارد خدمات را برای وب سایت شما حفظ می کند.

این بخش سناریویی را توصیف می‌کند که در آن کاربر یک ویدیوی جدید به نام "My Travels.mp4" ایجاد می‌کند و سپس سعی می‌کند ویدیو را در یک وب‌سایت اشتراک‌گذاری ویدیو آپلود کند.

هنگام کار با Fetch، به راحتی می توان مسیر شادی را در نظر گرفت که کاربر با موفقیت ویدیو را آپلود می کند. با این حال، مسیرهای دیگری نیز وجود دارد که چندان هموار نیستند، اما توسعه دهندگان وب باید برای آنها برنامه ریزی کنند. چنین مسیرهایی (ناراضی) ممکن است به دلیل خطای کاربر، از طریق شرایط محیطی غیرمنتظره، یا به دلیل وجود اشکال در وب سایت اشتراک گذاری ویدیو اتفاق بیفتد.

نمونه هایی از خطاهای کاربر

  • کاربر یک فایل تصویری (مانند JPEG) را به جای فایل ویدئویی آپلود می کند.
  • کاربر شروع به آپلود فایل ویدیویی اشتباه می کند. سپس در قسمتی از آپلود، کاربر فایل ویدئویی صحیح را برای آپلود مشخص می کند.
  • کاربر به طور تصادفی روی "لغو آپلود" کلیک می کند در حالی که ویدیو در حال آپلود است.

نمونه هایی از تغییرات محیطی

  • هنگام آپلود ویدیو، اتصال اینترنت آفلاین می شود.
  • هنگام آپلود ویدیو، مرورگر مجددا راه اندازی می شود.
  • سرورهای وب‌سایت اشتراک‌گذاری ویدیو در حین آپلود ویدیو راه‌اندازی مجدد می‌شوند.

نمونه هایی از خطاهای وب سایت اشتراک گذاری ویدیو

  • وب‌سایت اشتراک‌گذاری ویدیو نمی‌تواند نام فایل با فاصله را مدیریت کند. به جای "My Travels.mp4" ، نامی مانند "My_Travels.mp4" یا "MyTravels.mp4" را انتظار دارد.
  • وب‌سایت اشتراک‌گذاری ویدیو نمی‌تواند ویدیویی را که بیش از حداکثر اندازه مجاز فایل باشد آپلود کند.
  • وب‌سایت اشتراک‌گذاری ویدیو از کدک ویدیویی در ویدیوی آپلود شده پشتیبانی نمی‌کند.

این نمونه ها می توانند و در دنیای واقعی اتفاق بیفتند. شاید در گذشته با چنین نمونه هایی مواجه شده باشید! بیایید یک مثال از هر یک از دسته های قبلی انتخاب کنیم و نکات زیر را مورد بحث قرار دهیم:

  • اگر سرویس اشتراک‌گذاری ویدیو نتواند با مثال ارائه شده مقابله کند، رفتار پیش‌فرض چیست؟
  • کاربر انتظار دارد در مثال چه اتفاقی بیفتد؟
  • چگونه می توانیم روند را بهبود بخشیم؟
اقدام کاربر شروع به آپلود فایل ویدیویی اشتباه می کند. سپس در قسمتی از آپلود، کاربر فایل ویدئویی صحیح را برای آپلود مشخص می کند.
به طور پیش فرض چه اتفاقی می افتد فایل اصلی به آپلود در پس‌زمینه ادامه می‌دهد در حالی که فایل جدید همزمان آپلود می‌شود.
آنچه کاربر انتظار دارد کاربر انتظار دارد که آپلود اصلی متوقف شود تا پهنای باند اینترنت اضافی هدر نرود.
چه چیزی را می توان بهبود بخشید جاوا اسکریپت درخواست Fetch برای فایل اصلی را قبل از شروع آپلود فایل جدید لغو می کند.
اقدام کاربر تا حدودی از طریق آپلود ویدیو اتصال اینترنت خود را از دست می دهد.
به طور پیش فرض چه اتفاقی می افتد به نظر می رسد نوار پیشرفت آپلود روی 50% گیر کرده است. در نهایت، Fetch API با وقفه مواجه می شود و داده های آپلود شده دور ریخته می شود. هنگامی که اتصال به اینترنت بازگشت، کاربر باید فایل خود را دوباره آپلود کند.
آنچه کاربر انتظار دارد کاربر انتظار دارد زمانی که فایل او آپلود نمی شود به او اطلاع داده شود، و انتظار دارند که آپلود آنها به طور خودکار با 50٪ از سرگیری مجدد زمانی که دوباره آنلاین هستند، از سر گرفته شود.
چه چیزی را می توان بهبود بخشید صفحه آپلود، کاربر را از مشکلات اتصال به اینترنت مطلع می کند و به کاربر اطمینان می دهد که با از سرگیری اتصال به اینترنت، آپلود از سر گرفته می شود.
اقدام وب‌سایت اشتراک‌گذاری ویدیو نمی‌تواند نام فایل با فاصله را مدیریت کند. به جای "My Travels.mp4"، انتظار نام هایی مانند "My_Travels.mp4" یا "MyTravels.mp4" را دارد.
به طور پیش فرض چه اتفاقی می افتد کاربر باید صبر کند تا آپلود به طور کامل تمام شود. هنگامی که فایل آپلود شد، و نوار پیشرفت "100٪" را نشان داد، نوار پیشرفت این پیام را نشان می دهد: "لطفا دوباره امتحان کنید."
آنچه کاربر انتظار دارد کاربر انتظار دارد قبل از شروع آپلود یا حداقل در اولین ثانیه از آپلود، از محدودیت های نام فایل مطلع شود.
چه چیزی را می توان بهبود بخشید در حالت ایده آل، سرویس اشتراک ویدیو از نام فایل ها با فاصله پشتیبانی می کند. گزینه های جایگزین این است که کاربر را از محدودیت های نام فایل قبل از شروع آپلود مطلع کنید. یا، سرویس اشتراک ویدیو باید آپلود را با یک پیام خطای دقیق رد کند.

با Fetch API خطاها را مدیریت کنید

توجه داشته باشید که نمونه‌های کد زیر await سطح بالا ( پشتیبانی مرورگر ) استفاده می‌کنند زیرا این ویژگی می‌تواند کد شما را ساده‌تر کند.

وقتی Fetch API خطا می دهد

این مثال از دستور بلوک try / catch استفاده می‌کند تا خطاهای موجود در بلوک try را بگیرد. به عنوان مثال، اگر Fetch API نتواند منبع مشخص شده را واکشی کند، خطا رخ می دهد. در یک بلوک 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 بالقوه را درک کنید. توسعه دهندگان Backend، عملیات توسعه دهندگان، و مهندسان خدمات گاهی اوقات می توانند بینش منحصر به فردی را در مورد موارد لبه احتمالی ارائه دهند که ممکن است شما پیش بینی نکنید.

وقتی خطایی در تجزیه پاسخ شبکه وجود دارد

این مثال کد نوع دیگری از خطا را نشان می دهد که می تواند با تجزیه بدنه پاسخ ایجاد شود. رابط 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)
}

نتیجه گیری

یکی از جنبه‌های مهم رسیدگی به خطاها، تعریف بخش‌های مختلفی است که ممکن است اشتباه کنند. برای هر سناریو، مطمئن شوید که یک نسخه بازگشتی مناسب برای کاربر در نظر گرفته اید. با توجه به درخواست واکشی، از خود سوالاتی بپرسید:

  • اگر سرور هدف از کار بیفتد چه اتفاقی می افتد؟
  • اگر Fetch یک پاسخ غیرمنتظره دریافت کند چه اتفاقی می‌افتد؟
  • اگر اتصال اینترنت کاربر قطع شود چه اتفاقی می افتد؟

بسته به پیچیدگی صفحه وب خود، می توانید فلوچارتی را نیز ترسیم کنید که عملکرد و رابط کاربری را برای سناریوهای مختلف توصیف می کند.