Questo articolo illustra alcuni approcci alla gestione degli errori quando si utilizza l'API Fetch. L'API Fetch ti consente di inviare una richiesta a una risorsa di rete remota. Quando effettui una chiamata di rete remota, la tua pagina web diventa soggetta a una serie di potenziali errori di rete.
Le sezioni seguenti descrivono potenziali errori e spiegano come scrivere codice che offra un livello ragionevole di funzionalità e sia resiliente a errori e condizioni di rete impreviste. Il codice resiliente mantiene soddisfatti gli utenti e garantisce un livello di servizio standard per il tuo sito web.
Anticipa 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 caricare il video su un sito web di condivisione video.
Quando utilizzi Fetch, è facile considerare il percorso ottimale in cui l'utente carica correttamente il video. Tuttavia, esistono altri percorsi non così semplici, che gli sviluppatori web devono pianificare. Questi percorsi (insoddisfacenti) possono verificarsi a causa di un errore dell'utente, di condizioni ambientali impreviste o di 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. A metà 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 modifiche ambientali
- La connessione a internet diventa offline durante il caricamento del video.
- Il browser si riavvia durante il caricamento del video.
- I server del sito web di condivisione video si riavviano durante il caricamento del video.
Esempi di errori relativi al sito web di condivisione di video
- Il sito di condivisione video non può gestire un nome file con uno spazio. Al posto di
"My Travels.mp4"
, è previsto un nome come"My_Travels.mp4"
o"MyTravels.mp4"
. - Il sito web di condivisione video non può caricare video che superano le dimensioni massime consentite dei file.
- Il sito web di condivisione video non supporta il codec video del video caricato.
Questi esempi possono e si verificano nel mondo reale. Forse hai già visto questi esempi in passato. Scegliamo un esempio per ciascuna delle categorie precedenti e discutiamo i seguenti punti:
- Qual è il comportamento predefinito se il servizio di condivisione video non è in grado di gestire l'esempio in questione?
- Cosa si aspetta l'utente nell'esempio?
- Come possiamo migliorare la procedura?
Gestire gli errori con l'API Fetch
Tieni presente che i seguenti esempi di codice utilizzano await
di primo livello (supporto del browser) perché questa funzionalità può semplificare il 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 riesce a recuperare la risorsa specificata, viene generato un errore. All'interno di un blocco catch
come questo, assicurati di offrire un'esperienza utente significativa. Se all'utente viene mostrato uno spinner, un'interfaccia utente comune che rappresenta una sorta di avanzamento, puoi eseguire le seguenti azioni all'interno di un blocco catch
:
- Rimuovi la rotellina dalla pagina.
- Fornisci messaggi utili che spieghino cosa non ha funzionato e quali opzioni sono disponibili per 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 un secondo momento.
try {
const response = await fetch('https://website');
} catch (error) {
// TypeError: Failed to fetch
console.log('There was an error', error);
}
In un secondo momento, mentre diagnostichi l'errore registrato, puoi scrivere un caso di test per rilevare questo tipo di errore prima che gli utenti si accorgano che c'è un problema. A seconda dell'errore, il test può essere 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 altri codici di stato, non restituisce un errore di rete, ma si risolve normalmente.
Per verificare che il codice di stato HTTP sia riuscito, puoi utilizzare una delle seguenti opzioni:
- Utilizza la proprietà
Response.ok
per determinare se il codice di stato rientra nell'intervallo da200
a299
. - Utilizza la proprietà
Response.status
per determinare se la risposta è andata a buon fine. - Utilizza altri metadati, ad esempio
Response.headers
, per valutare se la risposta è andata a buon fine.
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 è collaborare con le persone della tua organizzazione e del tuo team per comprendere i potenziali codici di stato di risposta HTTP. A volte, gli sviluppatori di backend, gli addetti alle operazioni di sviluppo e gli ingegneri di servizio possono fornire informazioni uniche su possibili casi limite che potresti non prevedere.
Quando si verifica un errore durante l'analisi della risposta di rete
Questo esempio di codice mostra un altro tipo di errore che può verificarsi durante l'analisi del corpo di una risposta. L'interfaccia Response
offre metodi pratici per analizzare diversi tipi di dati, come testo o JSON. Nel codice seguente, viene fatta una richiesta di rete a un servizio di test HTTP che restituisce una stringa HTML come corpo della risposta. Tuttavia, viene tentato 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 in modo che accetti una serie di formati di risposta e verificare che una risposta imprevista non interrompa la pagina web per l'utente.
Considera il seguente scenario: hai una risorsa remota che restituisce una risposta JSON valida ed è analizzata correttamente con il metodo Response.json()
. Può accadere che il servizio non sia disponibile. Al termine, viene restituito un valore 500 Internal Server Error
. Se durante l'analisi del JSON non vengono utilizzate tecniche di gestione degli errori appropriate, la pagina potrebbe non essere visualizzata dall'utente perché viene generato un errore non gestito.
Quando la richiesta di rete deve essere annullata prima del completamento
In questo esempio di codice viene utilizzato un elemento AbortController
per annullare una richiesta in corso di pubblicazione. Una richiesta in corso è una richiesta di rete che è stata avviata, ma non è stata completata.
Gli scenari in cui potresti dover annullare una richiesta in corso possono variare, ma in ultima analisi dipendono dal caso d'uso e dall'ambiente. Il seguente codice mostra come passare un AbortSignal
all'API Fetch. AbortSignal
è associato a un AbortController
, che 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 è definire le varie parti che possono andare storte. Per ogni scenario, assicurati di avere implementato un piano di riserva appropriato per l'utente. In merito a una richiesta di recupero, poniti domande come:
- Che cosa succede se il server di destinazione non è disponibile?
- Che cosa succede se Fetch riceve una risposta imprevista?
- Cosa succede se la connessione a internet dell'utente non va a buon fine?
A seconda della complessità della pagina web, puoi anche abbozzare un diagramma di flusso che descriva la funzionalità e l'interfaccia utente per diversi scenari.