Questo articolo illustra alcuni approcci alla gestione degli errori quando si utilizza l'API Fetch. L'API Fetch consente di effettuare una richiesta a una risorsa di rete remota. Quando effettui una chiamata di rete remota, la pagina web può essere soggetta a una serie di potenziali errori di rete.
Le seguenti sezioni descrivono i potenziali errori e come scrivere codice che fornisca un buon livello di funzionalità resiliente a errori e condizioni di rete impreviste. Il codice resiliente mantiene soddisfatti i tuoi utenti e mantiene un livello di servizio standard per il tuo sito web.
Prevedi potenziali errori di rete
Questa sezione descrive uno scenario in cui l'utente crea un nuovo video denominato
"My Travels.mp4"
e poi tenta di caricarlo su un sito web per la condivisione di video.
Quando si lavora con Fetch, è facile considerare il percorso felice con cui l'utente carica correttamente il video. Tuttavia, esistono altri percorsi che non sono così semplici, ma che gli sviluppatori web devono pianificare. Questi percorsi (insoddisfatti) possono essere dovuti a un errore dell'utente, a condizioni ambientali impreviste o a un bug sul sito web di condivisione video.
Esempi di errori utente
- L'utente carica un file immagine (ad esempio JPEG) anziché un file video.
- L'utente inizia a caricare il file video sbagliato. Quindi, a metà del caricamento, l'utente specifica il file video corretto da caricare.
- L'utente fa clic accidentalmente su "Annulla caricamento" durante il caricamento del video.
Esempi di cambiamenti ambientali
- La connessione a internet si disconnette durante il caricamento del video.
- Il browser viene riavviato durante il caricamento del video.
- I server per il sito web di condivisione video si riavviano durante il caricamento del video.
Esempi di errori relativi al sito web di condivisione video
- Il sito web di condivisione video non può gestire un nome file con uno spazio. Invece di
"My Travels.mp4"
, è previsto un nome come"My_Travels.mp4"
o"MyTravels.mp4"
. - Il sito web di condivisione video non può caricare video di dimensioni superiori al limite massimo accettabile.
- Il sito web di condivisione video non supporta il codec video nel video caricato.
Questi esempi possono verificarsi, e di fatto, anche nel mondo reale. Potresti aver trovato questi esempi in passato. Scegliamo un esempio da ciascuna delle categorie precedenti e parliamo dei seguenti punti:
- Qual è il comportamento predefinito se il servizio di condivisione video non è in grado di gestire l'esempio indicato?
- Cosa si aspetta l'utente che accada nell'esempio?
- Come possiamo migliorare la procedura?
Gestire gli errori con l'API Fetch
Tieni presente che i seguenti esempi di codice utilizzano il await
di primo livello (supporto del browser) perché questa funzionalità può semplificare il tuo codice.
Quando l'API Fetch genera errori
Questo esempio utilizza un'istruzione blocco try
/catch
per rilevare eventuali errori generati all'interno del blocco try
. Ad esempio, se l'API Fetch non è in grado di recuperare la risorsa specificata, viene visualizzato un errore. All'interno di un blocco catch
come questo, assicurati di offrire un'esperienza utente significativa. Se viene mostrato all'utente uno rotellina, un'interfaccia utente comune che rappresenta i progressi, puoi eseguire le seguenti azioni all'interno di un blocco catch
:
- Rimuovi la rotellina dalla pagina.
- Fornisci messaggi utili che spieghino cosa è andato storto e quali opzioni può intraprendere l'utente.
- In base alle opzioni disponibili, presenta all'utente un pulsante "Riprova".
- Dietro le quinte, invia i dettagli dell'errore al tuo servizio di monitoraggio degli errori o al back-end. Questa azione registra l'errore in modo che possa essere diagnosticato in una fase successiva.
try {
const response = await fetch('https://website');
} catch (error) {
// TypeError: Failed to fetch
console.log('There was an error', error);
}
In una fase successiva, durante la diagnosi dell'errore che hai registrato, puoi scrivere uno scenario di test per rilevare l'errore prima che gli utenti si rendano conto che si è verificato un problema. A seconda dell'errore, il test potrebbe consistere in un test di unità, di integrazione o di accettazione.
Quando il codice di stato della rete rappresenta un errore
Questo esempio di codice invia una richiesta a un servizio di test HTTP che risponde sempre con il codice di stato HTTP 429 Too Many Requests
. È interessante notare che la risposta non raggiunge il blocco catch
. Uno stato 404, tra alcuni altri codici di stato, non restituisce un errore di rete, ma si risolve normalmente.
Per verificare che il codice di stato HTTP sia stato eseguito correttamente, puoi utilizzare una delle seguenti opzioni:
- Utilizza la proprietà
Response.ok
per determinare se il codice di stato è compreso tra200
e299
. - Utilizza la proprietà
Response.status
per determinare se la risposta è riuscita. - Utilizza qualsiasi altro metadati, come
Response.headers
, per valutare se la risposta è riuscita.
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}`)
}
La best practice consiste nel collaborare con le persone della tua organizzazione e del tuo team per comprendere i potenziali codici di stato delle risposte HTTP. Gli sviluppatori di backend, le operazioni degli sviluppatori e i tecnici dei servizi a volte possono fornire insight unici su possibili casi limite che potresti non prevedere.
In caso di errore durante l'analisi della risposta della rete
Questo esempio di codice mostra un altro tipo di errore che può verificarsi con l'analisi del corpo di una risposta. L'interfaccia di Response
offre pratici metodi per analizzare diversi tipi di dati, ad esempio testo o JSON. Nel codice seguente, viene effettuata una richiesta di rete a un servizio di test HTTP che restituisce una stringa HTML come corpo della risposta. Tuttavia, viene effettuato un tentativo di analizzare il corpo della risposta come JSON, generando un errore.
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);
}
Devi preparare il codice per accettare diversi formati di risposta e verificare che una risposta imprevista non comprometta la pagina web dell'utente.
Considera lo scenario seguente: hai una risorsa remota che restituisce una risposta JSON valida e viene analizzata correttamente con il metodo Response.json()
. Può succedere che il servizio non sia disponibile. Una volta terminato, viene restituito un 500 Internal Server Error
. Se durante l'analisi di JSON non vengono utilizzate tecniche appropriate di gestione degli errori, ciò potrebbe interrompere la pagina per l'utente a causa di un errore non gestito.
Quando la richiesta di rete deve essere annullata prima del completamento
Questo esempio di codice utilizza un elemento AbortController
per annullare una richiesta in corso. Una richiesta in corso è una richiesta di rete che è stata avviata, ma non è stata completata.
Gli scenari in cui potrebbe essere necessario annullare una richiesta in corso possono variare, ma in definitiva dipendono dal caso d'uso e dall'ambiente. Il seguente codice mostra come passare un elemento AbortSignal
all'API Fetch. Il AbortSignal
è collegato a un AbortController
e il AbortController
include un metodo abort()
, che indica al browser che la richiesta di rete deve essere annullata.
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)
}
Conclusione
Un aspetto importante della gestione degli errori è la definizione delle varie parti che possono andare storte. Per ogni scenario, assicurati di disporre di un'opzione di riserva appropriata per l'utente. In merito a una richiesta di recupero, poniti domande quali:
- Cosa succede se il server di destinazione non è disponibile?
- Che cosa succede se il recupero riceve una risposta imprevista?
- Cosa succede se la connessione a internet dell'utente non riesce?
A seconda della complessità della tua pagina web, puoi anche tracciare un diagramma di flusso che descriva la funzionalità e l'interfaccia utente per scenari diversi.