บทความนี้สาธิตวิธีการจัดการข้อผิดพลาดเมื่อทำงานกับ Fetch API API การดึงข้อมูลช่วยให้คุณส่งคำขอไปยังทรัพยากรเครือข่ายระยะไกลได้ เมื่อคุณทำการโทรผ่านเครือข่ายระยะไกล หน้าเว็บของคุณอาจมีข้อผิดพลาดเกี่ยวกับเครือข่ายที่อาจเกิดขึ้นได้หลายประการ
ส่วนต่อไปนี้จะอธิบายข้อผิดพลาดที่อาจเกิดขึ้นและอธิบายวิธีเขียนโค้ดที่มีระดับฟังก์ชันการทำงานที่เหมาะสมและมีความยืดหยุ่นต่อข้อผิดพลาดและเงื่อนไขที่ไม่คาดคิดของเครือข่าย โค้ดที่ยืดหยุ่นช่วยให้ผู้ใช้พึงพอใจและรักษาระดับการให้บริการมาตรฐานสำหรับเว็บไซต์ของคุณ
ป้องกันข้อผิดพลาดที่อาจเกิดขึ้นกับเครือข่าย
ส่วนนี้อธิบายสถานการณ์ที่ผู้ใช้สร้างวิดีโอใหม่ชื่อ "My Travels.mp4"
และพยายามอัปโหลดวิดีโอไปยังเว็บไซต์แชร์วิดีโอ
เมื่อใช้งานการดึงข้อมูล เป็นเรื่องง่ายที่จะคำนึงถึงเส้นทางแห่งความสุขที่ผู้ใช้อัปโหลดวิดีโอได้สำเร็จ อย่างไรก็ตาม เส้นทางอื่นๆ ก็ไม่ราบรื่นเท่าที่ควร ซึ่งนักพัฒนาเว็บจะต้องวางแผนล่วงหน้า เส้นทางดังกล่าว (ไม่น่าพอใจ) อาจเกิดจากข้อผิดพลาดของผู้ใช้ ผ่านสภาพแวดล้อมที่ไม่คาดคิด หรือข้อบกพร่องในเว็บไซต์แชร์วิดีโอ
ตัวอย่างข้อผิดพลาดของผู้ใช้
- ผู้ใช้อัปโหลดไฟล์ภาพ (เช่น JPEG) แทนไฟล์วิดีโอ
- ผู้ใช้เริ่มอัปโหลดไฟล์วิดีโอที่ไม่ถูกต้อง จากนั้น ผู้ใช้ระบุไฟล์วิดีโอที่ถูกต้องสำหรับการอัปโหลดในระหว่างการอัปโหลด
- ผู้ใช้คลิก "ยกเลิกการอัปโหลด" โดยไม่ได้ตั้งใจขณะกำลังอัปโหลด
ตัวอย่างการเปลี่ยนแปลงด้านสิ่งแวดล้อม
- การเชื่อมต่ออินเทอร์เน็ตจะออฟไลน์ในระหว่างอัปโหลดวิดีโอ
- เบราว์เซอร์จะรีสตาร์ทขณะอัปโหลดวิดีโอ
- เซิร์ฟเวอร์ของเว็บไซต์แชร์วิดีโอจะรีสตาร์ทขณะอัปโหลดวิดีโอ
ตัวอย่างข้อผิดพลาดของเว็บไซต์แชร์วิดีโอ
- เว็บไซต์แชร์วิดีโอจัดการชื่อไฟล์ด้วยการเว้นวรรคไม่ได้ แทนที่จะใช้
"My Travels.mp4"
ระบบจะใช้ชื่ออย่างเช่น"My_Travels.mp4"
หรือ"MyTravels.mp4"
- เว็บไซต์แชร์วิดีโอไม่สามารถอัปโหลดวิดีโอที่มีขนาดเกินขนาดไฟล์สูงสุดที่ยอมรับได้
- เว็บไซต์แชร์วิดีโอไม่รองรับตัวแปลงรหัสวิดีโอในวิดีโอที่อัปโหลด
ตัวอย่างเหล่านี้สามารถเกิดขึ้นได้ในชีวิตจริง คุณอาจเคยเห็นตัวอย่างเช่นนี้มาก่อน เราจะเลือกตัวอย่างหนึ่งตัวอย่างจากแต่ละหมวดหมู่ก่อนหน้านี้ และพูดถึงประเด็นต่อไปนี้
- ลักษณะการทำงานเริ่มต้นคืออะไรหากบริการแชร์วิดีโอจัดการตัวอย่างที่ระบุไม่ได้
- ผู้ใช้คาดหวังว่าจะเกิดอะไรขึ้นในตัวอย่างนี้
- เราจะปรับปรุงกระบวนการนี้ได้อย่างไร
จัดการข้อผิดพลาดด้วย Fetch API
โปรดทราบว่าตัวอย่างโค้ดต่อไปนี้ใช้await
ระดับบนสุด (การรองรับเบราว์เซอร์) เนื่องจากฟีเจอร์นี้ช่วยลดความซับซ้อนของโค้ดได้
เมื่อ Fetch API แสดงข้อผิดพลาด
ตัวอย่างนี้ใช้คำสั่ง try
/catch
Block เพื่อตรวจหาข้อผิดพลาดใดก็ตามที่อยู่ภายในบล็อก try
ตัวอย่างเช่น หาก Fetch API ดึงข้อมูลทรัพยากรที่ระบุไม่ได้ ระบบจะแสดงข้อผิดพลาด ภายใน 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)
}
บทสรุป
แง่มุมหนึ่งที่สำคัญของการจัดการข้อผิดพลาดคือการกำหนดส่วนต่างๆ ที่อาจผิดพลาดได้ ในแต่ละสถานการณ์ โปรดตรวจสอบว่าคุณมีทางเลือกสำรองที่เหมาะสมสำหรับผู้ใช้ เกี่ยวกับคําขอดึงข้อมูล ให้ถามตัวเองคําถามต่อไปนี้ เช่น
- จะเกิดอะไรขึ้นหากเซิร์ฟเวอร์เป้าหมายหยุดทำงาน
- จะเกิดอะไรขึ้นหากการดึงข้อมูลได้รับการตอบสนองที่ไม่คาดคิด
- จะเกิดอะไรขึ้นหากการเชื่อมต่ออินเทอร์เน็ตของผู้ใช้ล้มเหลว
คุณยังสามารถร่างโฟลว์ชาร์ตที่อธิบายฟังก์ชันและอินเทอร์เฟซผู้ใช้สําหรับสถานการณ์ต่างๆ ได้เช่นกัน ทั้งนี้ขึ้นอยู่กับความซับซ้อนของหน้าเว็บ