Implementa la gestione degli errori durante l'utilizzo dell'API Fetch

Umar Hansa
Umar Hansa

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?
Azione L'utente inizia a caricare il file video sbagliato. Quindi, a metà del caricamento, l'utente specifica il file video corretto da caricare.
Cosa succede per impostazione predefinita Il caricamento del file originale continua in background mentre il nuovo file viene caricato contemporaneamente.
Che cosa si aspetta l'utente L'utente si aspetta che il caricamento originale venga interrotto, per non sprecare ulteriore larghezza di banda internet.
Che cosa può essere migliorato JavaScript annulla la richiesta di recupero del file originale prima che inizi il caricamento del nuovo file.
Azione L'utente perde la connessione a internet a metà del caricamento del video.
Cosa succede per impostazione predefinita La barra di avanzamento del caricamento sembra essere bloccata al 50%. Alla fine, l'API Fetch si verifica in timeout e i dati caricati vengono ignorati. Quando viene ripristinata la connessione a internet, l'utente deve ricaricare il file.
Che cosa si aspetta l'utente L'utente si aspetta di ricevere una notifica quando il file non può essere caricato e il caricamento riprenderà automaticamente al 50% quando sarà di nuovo online.
Che cosa può essere migliorato La pagina di caricamento informa l'utente in caso di problemi di connessione a internet e lo rassicura sul fatto che il caricamento riprenderà una volta ripristinata la connessione a internet.
Azione Il sito web di condivisione video non può gestire un nome file con uno spazio. Invece di "My Travels.mp4", si aspetta nomi come "My_Travels.mp4" o "MyTravels.mp4".
Cosa succede per impostazione predefinita L'utente deve attendere il completamento del caricamento. Dopo aver caricato il file e se nella barra di avanzamento è indicato "100%", nella barra di avanzamento viene visualizzato il messaggio "Riprova".
Che cosa si aspetta l'utente L'utente si aspetta di ricevere notifiche relative alle limitazioni relative ai nomi file prima dell'inizio del caricamento o almeno entro il primo secondo dal caricamento.
Che cosa può essere migliorato Idealmente, il servizio di condivisione video supporta i nomi file con spazi. Le opzioni alternative consistono nel notificare all'utente le limitazioni relative ai nomi dei file prima dell'inizio del caricamento. In alternativa, il servizio di condivisione video dovrebbe rifiutare il caricamento con un messaggio di errore dettagliato.

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:

  1. Rimuovi la rotellina dalla pagina.
  2. Fornisci messaggi utili che spieghino cosa è andato storto e quali opzioni può intraprendere l'utente.
  3. In base alle opzioni disponibili, presenta all'utente un pulsante "Riprova".
  4. 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 tra 200 e 299.
  • 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.