Bài viết này trình bày một số phương pháp xử lý lỗi khi làm việc với API Tìm nạp. API Tìm nạp cho phép bạn gửi yêu cầu đến một tài nguyên mạng từ xa. Khi bạn thực hiện một cuộc gọi mạng từ xa, trang web của bạn sẽ gặp phải nhiều lỗi mạng có thể xảy ra.
Các phần sau đây mô tả các lỗi có thể xảy ra và mô tả cách viết mã cung cấp chức năng hợp lý có khả năng thích ứng với lỗi và điều kiện mạng không mong muốn. Mã có khả năng chống chịu giúp người dùng hài lòng và duy trì cấp dịch vụ tiêu chuẩn cho trang web của bạn.
Dự đoán các lỗi mạng có thể xảy ra
Phần này mô tả tình huống trong đó người dùng tạo một video mới có tên là
"My Travels.mp4"
rồi cố tải video đó lên một trang web chia sẻ video.
Khi làm việc với Tìm nạp, bạn có thể dễ dàng xem xét đường dẫn hạnh phúc nơi người dùng tải video lên thành công. Tuy nhiên, có những lộ trình khác không suôn sẻ mà các nhà phát triển web phải lên kế hoạch. Các đường dẫn (không vui) như vậy có thể xảy ra do lỗi người dùng, thông qua các điều kiện môi trường không mong muốn hoặc do lỗi trên trang web chia sẻ video.
Ví dụ về lỗi người dùng
- Người dùng tải tệp hình ảnh lên (chẳng hạn như JPEG) thay vì tệp video.
- Người dùng bắt đầu tải sai tệp video lên. Trong quá trình tải lên, người dùng chỉ định đúng tệp video để tải lên.
- Người dùng vô tình nhấp vào "Hủy tải lên" trong khi video đang tải lên.
Ví dụ về những thay đổi về môi trường
- Kết nối Internet bị ngắt kết nối trong khi video đang tải lên.
- Trình duyệt sẽ khởi động lại trong lúc video đang tải lên.
- Máy chủ của trang web chia sẻ video sẽ khởi động lại trong khi video đang tải lên.
Ví dụ về lỗi với trang web chia sẻ video
- Trang web chia sẻ video không thể xử lý tên tệp có dấu cách. Thay vì
"My Travels.mp4"
, lớp này sẽ nhận một tên như"My_Travels.mp4"
hoặc"MyTravels.mp4"
. - Trang web chia sẻ video không thể tải lên video vượt quá kích thước tệp tối đa được chấp nhận.
- Trang web chia sẻ video không hỗ trợ bộ mã hoá và giải mã video trong video được tải lên.
Những ví dụ này có thể và xảy ra trong thực tế. Có thể bạn đã từng gặp những trường hợp như vậy! Hãy chọn một ví dụ từ mỗi danh mục trước và thảo luận về các điểm sau:
- Đâu là hành vi mặc định nếu dịch vụ chia sẻ video không thể xử lý ví dụ đã nêu?
- Người dùng mong đợi điều gì sẽ xảy ra trong ví dụ này?
- Chúng tôi có thể làm gì để cải thiện quy trình này?
Xử lý lỗi bằng API Tìm nạp
Xin lưu ý rằng các mã ví dụ sau đây sử dụng await
cấp cao nhất (hỗ trợ trình duyệt) vì tính năng này có thể đơn giản hoá mã của bạn.
Khi API Tìm nạp gửi lỗi
Ví dụ này sử dụng câu lệnh khối try
/catch
để phát hiện mọi lỗi được tạo ra trong khối try
. Ví dụ: nếu API Tìm nạp không thể tìm nạp tài nguyên được chỉ định, thì hệ thống sẽ báo lỗi. Trong khối catch
như thế này, hãy chú ý cung cấp trải nghiệm người dùng có ý nghĩa. Nếu người dùng thấy một vòng quay (giao diện người dùng phổ biến đại diện cho một loại tiến trình nào đó), thì bạn có thể thực hiện các thao tác sau trong khối catch
:
- Xoá vòng quay này khỏi trang.
- Đưa ra thông báo hữu ích để giải thích lỗi và những lựa chọn mà người dùng có thể chọn.
- Dựa vào các lựa chọn có sẵn, hãy cho người dùng thấy nút "Thử lại".
- Trong hậu trường, hãy gửi thông tin chi tiết về lỗi cho dịch vụ theo dõi lỗi hoặc dịch vụ hỗ trợ. Thao tác này sẽ ghi lại lỗi để có thể chẩn đoán ở giai đoạn sau.
try {
const response = await fetch('https://website');
} catch (error) {
// TypeError: Failed to fetch
console.log('There was an error', error);
}
Ở giai đoạn sau, trong khi chẩn đoán lỗi mà bạn đã ghi lại, bạn có thể viết trường hợp kiểm thử để phát hiện lỗi như vậy trước khi người dùng biết đã xảy ra lỗi. Tuỳ thuộc vào lỗi, kiểm thử có thể là kiểm thử đơn vị, kiểm thử tích hợp hoặc kiểm thử chấp nhận.
Khi mã trạng thái mạng báo lỗi
Ví dụ về mã này gửi yêu cầu tới một dịch vụ kiểm thử HTTP luôn phản hồi bằng mã trạng thái HTTP 429 Too Many Requests
. Điều thú vị là phản hồi không tiếp cận được khối catch
. Trạng thái 404, cùng với một số mã trạng thái khác, không trả về lỗi mạng mà giải quyết bình thường.
Để kiểm tra xem mã trạng thái HTTP có thành công hay không, bạn có thể sử dụng bất kỳ tuỳ chọn nào sau đây:
- Sử dụng thuộc tính
Response.ok
để xác định xem mã trạng thái có nằm trong khoảng từ200
đến299
hay không. - Sử dụng thuộc tính
Response.status
để xác định xem phản hồi có thành công hay không. - Sử dụng bất kỳ siêu dữ liệu nào khác, chẳng hạn như
Response.headers
, để đánh giá xem phản hồi có thành công hay không.
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}`)
}
Cách tốt nhất là làm việc với mọi người trong tổ chức và nhóm của bạn để hiểu các mã trạng thái phản hồi HTTP tiềm năng. Nhà phát triển phụ trợ, kỹ sư vận hành của nhà phát triển và kỹ sư dịch vụ đôi khi có thể cung cấp thông tin chi tiết độc đáo về các trường hợp hiếm gặp mà bạn không lường trước được.
Khi xảy ra lỗi khi phân tích cú pháp phản hồi mạng
Ví dụ về mã này minh hoạ một loại lỗi khác có thể phát sinh khi phân tích cú pháp nội dung phản hồi. Giao diện Response
cung cấp các phương thức thuận tiện để phân tích cú pháp nhiều loại dữ liệu, chẳng hạn như văn bản hoặc JSON. Trong mã sau, một yêu cầu mạng được gửi đến dịch vụ kiểm thử HTTP trả về một chuỗi HTML dưới dạng nội dung phản hồi. Tuy nhiên, hệ thống sẽ cố gắng phân tích cú pháp nội dung phản hồi dưới dạng JSON và gửi ra một lỗi.
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);
}
Bạn phải chuẩn bị mã để chấp nhận nhiều định dạng phản hồi và xác minh rằng một phản hồi không mong muốn không làm hỏng trang web cho người dùng.
Hãy xem xét trường hợp sau: Bạn có một tài nguyên từ xa trả về phản hồi JSON hợp lệ và tài nguyên đó được phân tích cú pháp thành công bằng phương thức Response.json()
. Có thể dịch vụ ngừng hoạt động. Sau khi thanh toán xuống, hàm 500 Internal Server Error
sẽ được trả về. Nếu bạn không sử dụng các kỹ thuật xử lý lỗi thích hợp trong quá trình phân tích cú pháp JSON, thì điều này có thể khiến trang bị hỏng cho người dùng do xảy ra lỗi không được xử lý.
Khi yêu cầu kết nối mạng phải bị huỷ trước khi hoàn tất
Ví dụ về mã này sử dụng AbortController
để huỷ một yêu cầu đang được tiến hành. Yêu cầu đang tiến hành là một yêu cầu mạng đã bắt đầu nhưng chưa hoàn tất.
Các trường hợp bạn có thể cần phải huỷ một yêu cầu đang được tiến hành có thể khác nhau, nhưng cuối cùng điều này phụ thuộc vào trường hợp sử dụng và môi trường của bạn. Mã sau đây minh hoạ cách chuyển AbortSignal
đến API Tìm nạp. AbortSignal
được đính kèm vào AbortController
và AbortController
bao gồm một phương thức abort()
, cho trình duyệt biết rằng yêu cầu mạng cần được huỷ.
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)
}
Kết luận
Một khía cạnh quan trọng trong quá trình xử lý lỗi là xác định các phần có thể xảy ra lỗi. Đối với mỗi trường hợp, hãy đảm bảo bạn có một phương án dự phòng thích hợp cho người dùng. Đối với yêu cầu tìm nạp, hãy tự đặt ra các câu hỏi như:
- Điều gì sẽ xảy ra nếu máy chủ đích ngừng hoạt động?
- Điều gì xảy ra nếu Tìm nạp nhận được phản hồi không mong muốn?
- Điều gì xảy ra nếu kết nối Internet của người dùng bị lỗi?
Tuỳ thuộc vào độ phức tạp của trang web, bạn cũng có thể phác thảo sơ đồ quy trình mô tả chức năng và giao diện người dùng trong các tình huống khác nhau.