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 wywołanie sieci zdalnej, Twoja strona internetowa może być narażona na różne potencjalne błędy sieciowe.
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. Stabilny kod dba o zadowolenie użytkowników i pozwala utrzymać standardowy poziom obsługi witryny.
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ą wystąpić z powodu błędu użytkownika, nieoczekiwanych warunków środowiskowych lub błędu 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 nieprawidłowego 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 w środowisku
- Podczas przesyłania filmu połączenie z internetem zostanie przerwane.
- 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 może obsłużyć nazwy pliku z spacją. 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 jest w stanie obsłużyć podanego przykładu?
- Czego użytkownik oczekuje w tym przykładzie?
- Jak możemy ulepszyć ten proces?
Obsługa błędów w 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.
Kiedy interfejs Fetch API zgłasza 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 w bloku catch
wyświetlany jest wskaźnik postępu, czyli wspólny interfejs użytkownika reprezentujący pewne postępy:
- Usuń wskaźnik postępu ze strony.
- Wyświetlaj przydatne informacje o problemach i opcjach dostępnych dla użytkownika.
- Zależnie od dostępnych opcji zamieść 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 było go 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);
}
Na późniejszym etapie, gdy będziesz diagnozować zarejestrowany błąd, możesz napisać przypadek testowy, aby wychwytywać taki błąd, zanim użytkownicy dowiedzą się, ż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, ale 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 sprawdzić, czy kod stanu mieścił się w zakresie od200
do299
. - Aby określić, czy odpowiedź została wysłana, użyj właściwości
Response.status
. - Aby ocenić, czy odpowiedź się udała, użyj 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 skonsultować się z osobami z Twojej organizacji i zespołu, aby poznać możliwe kody 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, takich jak tekst lub plik JSON. W poniższym kodzie żądanie sieciowe jest wysyłane do usługi testowania HTTP, która zwraca ciąg HTML jako treść odpowiedzi. Jednak próba przeanalizowania treści odpowiedzi jako JSON kończy się błędem.
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ć swój kod do przyjmowania różnych formatów odpowiedzi i sprawdzić, czy nieoczekiwana odpowiedź nie powoduje problemów ze stroną internetową 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 funkcji zwracany jest parametr 500 Internal Server Error
. Jeśli podczas analizy pliku JSON nie są używane odpowiednie techniki obsługi błędów, może to doprowadzić do problemów ze stroną użytkownika, ponieważ zgłaszany jest nieobsługiwany błąd.
Kiedy żądanie sieci musi zostać anulowane przed zakończeniem
W tym przykładzie kodu użyto elementu AbortController
, aby anulować bieżące żądanie. Przesyłane żądanie to żądanie sieciowe, które zostało rozpoczęte, ale nie zostało jeszcze zakończone.
Wymagania anulowania żądania w trakcie realizacji mogą się różnić, ale ostatecznie wszystko zależy od przypadku użycia i środowiska. Ten kod pokazuje, jak przekazać 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. Na temat żądania pobierania zadaj sobie następujące pytania:
- 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 funkcjonalność i interfejs użytkownika w różnych scenariuszach.