Z tego artykułu dowiesz się, jak radzić sobie z błędami podczas korzystania z interfejsu Fetch API. Interfejs Fetch API umożliwia wysyłanie żądań do zdalnego zasobu sieciowego. Gdy wysyłasz zdalne wywołanie sieci, Twoja strona internetowa może być narażona na różne potencjalne błędy sieci.
W następnych sekcjach opisujemy potencjalne błędy i podajemy wskazówki, jak pisać kod, który zapewnia odpowiedni poziom funkcjonalności i jest odporny na błędy oraz nieoczekiwane warunki sieciowe. Dzięki odpornemu kodom użytkownicy są zadowoleni, a Twoja witryna zapewnia standardowy poziom usług.
Zapobieganie potencjalnym błędom sieci
W tej sekcji opisujemy scenariusz, w którym użytkownik tworzy nowy film o nazwie "My Travels.mp4"
, a następnie próbuje przesłać go na stronę do udostępniania filmów.
Podczas pracy z Fetch łatwo jest wziąć pod uwagę sytuację idealną, w której użytkownik przesyła film. Istnieją jednak inne ścieżki, które nie są tak płynne, ale twórcy stron internetowych muszą je uwzględnić w planowaniu. Takie (nieszczęśliwe) ścieżki mogą być spowodowane błędem użytkownika, nieoczekiwanymi warunkami środowiskowymi lub błędem w witrynie do udostępniania filmów.
Przykłady błędów popełnianych przez użytkowników
- Użytkownik przesyła plik obrazu (np. JPEG) zamiast pliku wideo.
- Użytkownik rozpoczyna przesyłanie niewłaściwego pliku wideo. Następnie, w połowie przesyłania, użytkownik wskazuje odpowiedni plik wideo do przesłania.
- Użytkownik przypadkowo klika „Anuluj przesyłanie” podczas przesyłania filmu.
Przykłady zmian środowiskowych
- połączenie z internetem zostanie utracone podczas przesyłania filmu.
- Podczas przesyłania filmu przeglądarka się restartuje.
- Serwery witryny do udostępniania filmów są ponownie uruchamiane podczas przesyłania filmu.
Przykłady błędów w witrynie do udostępniania filmów
- Witryna do udostępniania filmów nie obsługuje nazw plików zawierających spacje. Zamiast
"My Travels.mp4"
oczekuje się nazwy takiej jak"My_Travels.mp4"
lub"MyTravels.mp4"
. - Witryna do udostępniania filmów nie może przesłać filmu, którego rozmiar przekracza maksymalny dopuszczalny rozmiar pliku.
- Witryna do udostępniania filmów nie obsługuje kodeka wideo w przesłanym filmie.
Te przykłady mogą się zdarzyć w rzeczywistych sytuacjach. Być może już wcześniej spotykałeś się z takimi przykładami. Wybierzmy po jednym przykładzie z każdej z tych kategorii i omówimy te kwestie:
- Jakie jest domyślne działanie, jeśli usługa udostępniania filmów nie może obsłużyć danego przykładu?
- Czego użytkownik oczekuje w tym przykładzie?
- Jak możemy ulepszyć ten proces?
Obsługa błędów w interfejsie Fetch API
Pamiętaj, że poniższe przykłady kodu używają poziomu najwyższego await
(obsługa w przeglądarce), ponieważ ta funkcja może uprościć kod.
Gdy interfejs Fetch API zwraca błędy
W tym przykładzie użyto instrukcji try
/catch
, aby przechwytywać błędy zgłaszane w bloku try
. Jeśli na przykład interfejs Fetch API nie może pobrać określonego zasobu, zostanie wygenerowany błąd. W bloku catch
takiego jak ten zadbaj o dobre wrażenia użytkowników. Jeśli użytkownikowi wyświetla się spinner, czyli element interfejsu użytkownika przedstawiający postęp, możesz wykonać w bloku catch
te czynności:
- Usuń spinner ze strony.
- wyświetlić przydatne komunikaty wyjaśniające, co poszło nie tak, i jakie opcje ma użytkownik;
- W zależności od dostępnych opcji wyświetl użytkownikowi przycisk „Spróbuj ponownie”.
- W tle wyślij szczegóły błędu do usługi śledzenia błędów lub do backendu. To działanie rejestruje błąd, aby można go było zdiagnozować na późniejszym etapie.
try {
const response = await fetch('https://website');
} catch (error) {
// TypeError: Failed to fetch
console.log('There was an error', error);
}
Później, podczas diagnozowania zarejestrowanego błędu, możesz napisać przypadek testowy, aby wykrywać takie błędy, zanim użytkownicy zauważą, że coś jest nie tak. W zależności od błędu test może być testem jednostkowym, testem integracji lub testem akceptacyjnym.
Gdy kod stanu sieci oznacza błąd
Ten przykład kodu wysyła żądanie do usługi testowania HTTP, która zawsze odpowiada kodem stanu HTTP 429 Too Many Requests
. Co ciekawe, odpowiedź nie dociera do bloku catch
. Stan 404, podobnie jak niektóre inne kody stanu, nie zwraca błędu sieci, lecz jest normalnie rozwiązywany.
Aby sprawdzić, czy kod stanu HTTP jest prawidłowy, możesz użyć jednej z tych opcji:
- Użyj właściwości
Response.ok
, aby określić, czy kod stanu mieścił się w zakresie od200
do299
. - Aby sprawdzić, czy odpowiedź została prawidłowo wysłana, użyj właściwości
Response.status
. - Aby ocenić, czy odpowiedź była prawidłowa, użyj dowolnych innych metadanych, np.
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}`)
}
Najlepiej skontaktować się z osobami z Twojej organizacji i zespołu, aby dowiedzieć się więcej o potencjalnych kodach stanu odpowiedzi HTTP. Deweloperzy backendu, specjaliści ds. operacji deweloperskich i inżynierowie serwisu mogą czasami dostarczyć unikalnych informacji o możliwych przypadkach skrajnych, których nie można przewidzieć.
Gdy wystąpi błąd podczas analizowania odpowiedzi sieci
Ten przykład kodu pokazuje inny typ błędu, który może wystąpić podczas analizowania treści odpowiedzi. Interfejs Response
oferuje wygodne metody analizowania różnych typów danych, np. tekstu lub JSON. W tym kodzie wysyłane jest żądanie sieciowe do usługi testowania HTTP, która zwraca ciąg tekstowy HTML jako treść odpowiedzi. Jednak próba przeanalizowania treści odpowiedzi jako JSON powoduje błąd.
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);
}
Musisz przygotować kod, aby obsługiwał różne formaty odpowiedzi, i sprawdzić, czy nieoczekiwana odpowiedź nie spowoduje błędu w stronie internetowej użytkownika.
Rozważmy taki scenariusz: masz zdalny zasób, który zwraca prawidłową odpowiedź JSON i jest on poprawnie analizowany za pomocą metody Response.json()
. Może się zdarzyć, że usługa przestanie działać. Po zakończeniu działania funkcja zwraca wartość 500 Internal Server Error
. Jeśli podczas analizowania pliku JSON nie zostaną użyte odpowiednie techniki obsługi błędów, może to spowodować nieprawidłowe działanie strony dla użytkownika, ponieważ zostanie wygenerowany nieobsługiwany błąd.
Kiedy żądanie sieci musi zostać anulowane przed zakończeniem
W tym przykładzie kodu użyto elementu AbortController
, aby anulować żądanie w trakcie przetwarzania. Przesyłane żądanie to żądanie sieciowe, które zostało rozpoczęte, ale nie zostało jeszcze zakończone.
Wymagania anulowania bieżącego żądania mogą się różnić, ale ostatecznie wszystko zależy od przypadku użycia i środowiska. Poniższy kod pokazuje, jak przekazać parametr AbortSignal
do interfejsu Fetch API. Element AbortSignal
jest dołączony do elementu AbortController
, a element AbortController
zawiera metodę abort()
, która informuje przeglądarkę, że żądanie sieci powinno zostać anulowane.
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)
}
Podsumowanie
Jednym z ważnych aspektów obsługi błędów jest określenie różnych elementów, które mogą się nie udać. W każdym scenariuszu upewnij się, że masz odpowiednią opcję zastępczą dla użytkownika. W przypadku żądania pobierania zadaj sobie pytania takie jak:
- Co się stanie, jeśli serwer docelowy przestanie działać?
- Co się stanie, jeśli Fetch otrzyma nieoczekiwaną odpowiedź?
- Co się stanie, jeśli połączenie internetowe użytkownika nie będzie działać?
W zależności od złożoności strony możesz też narysować schemat przepływu danych, który opisuje funkcje i interfejs użytkownika w różnych scenariuszach.