W3docs

Gestione degli errori nelle Promise JavaScript

Gestione degli errori nelle promise JavaScript: .catch(), propagazione del rifiuto, rilancio, .finally(), unhandledrejection e try/catch con async/await.

Le promise JavaScript sono una parte fondamentale della gestione delle operazioni asincrone, e consentono agli sviluppatori di gestire eventi asincroni con maggiore flessibilità e semplicità (vedi JavaScript: Promises). La gestione degli errori nelle promise è essenziale per scrivere codice JavaScript robusto, capace di affrontare problemi imprevisti senza mandare in crash l'applicazione.

Questo capitolo spiega come vengono intercettati i rifiuti, come gli errori si propagano attraverso una catena, come si rilanciano e si recuperano, il hook di pulizia .finally(), la rete di sicurezza globale unhandledrejection e come gli stessi pattern si applicano ad async/await. Se non hai ancora familiarità con il concatenamento delle chiamate .then(), leggi prima Concatenamento delle promise.

Una promise può terminare in uno di due stati: fulfilled (ha prodotto un valore) o rejected (qualcosa è andato storto). Un rifiuto avviene quando si chiama reject(...), quando si lancia un throw all'interno di un executor o di un callback .then(), oppure quando un'API asincrona nativa fallisce. La gestione degli errori consiste nell'instradare quei rifiuti verso un handler invece di lasciare che mandino in crash il programma.

La gestione degli errori nelle promise si realizza tramite il metodo .catch() oppure passando un secondo argomento al metodo .then(). Entrambi i metodi offrono modalità per gestire e recuperare dagli errori che si verificano durante l'esecuzione di operazioni asincrone.

Utilizzo del metodo .catch()

Il metodo .catch() viene utilizzato per intercettare qualsiasi errore che si verifichi durante l'esecuzione della catena di promise.


javascript— editable

Utilizzo del secondo argomento di .then()

In alternativa, è possibile passare un secondo argomento a .then() per gestire gli errori che si verificano dopo l'esecuzione del callback del primo argomento.


javascript— editable

Tecniche avanzate di gestione degli errori

Flusso degli errori nelle catene

Gli errori devono essere propagati correttamente attraverso la catena di promise per garantire che vengano gestiti al livello appropriato. Ad esempio, se si posiziona il blocco .catch() prima del blocco .then(), il blocco .then() verrà comunque eseguito. Poiché .catch() risolve la catena di promise (a meno che non rilanci un errore), il .then() successivo riceve undefined come argomento.

Attenzione

Quando si posiziona il blocco .catch() prima del blocco .then(), qualsiasi errore generato all'interno del .then() non verrà intercettato dal .catch() precedente. Verrà gestito solo aggiungendo un altro blocco .catch() dopo di esso.


javascript— editable

Propagazione del rifiuto

Non è necessario inserire un .catch() dopo ogni .then(). Un rifiuto salta tutti gli handler di successo (il primo argomento di .then()) e scende lungo la catena fino a raggiungere il primo .catch(). Questo consente di scrivere una lunga catena di passaggi e gestire qualsiasi errore in un unico punto alla fine.

Nell'esempio seguente, il rifiuto avviene fin dall'inizio, ma nessuno dei tre callback .then() viene eseguito — il controllo salta direttamente all'unico .catch():


javascript— editable

Rilancio e recupero

Un handler .catch() svolge due compiti a seconda di cosa fa:

  • Recupero — se restituisce un valore (o non restituisce nulla), la catena torna fulfilled e il .then() successivo viene eseguito con quel valore. È così che si fornisce un valore di fallback.
  • Rilancio — se lancia un throw (o restituisce una promise rifiutata), l'errore continua a propagarsi verso il successivo .catch(). Si usa quando un handler non è in grado di gestire completamente l'errore e vuole che un handler successivo completi il lavoro.

javascript— editable

Gestione di errori specifici

JavaScript consente strategie di gestione degli errori più articolate, come il filtraggio degli errori in base al loro tipo o alle specifiche circostanze dell'errore. Nel seguente esempio gestiamo un TypeError. Un TypeError si verifica tipicamente quando un valore non è del tipo atteso e pertanto l'operazione desiderata non può essere eseguita.


javascript— editable

Buone pratiche per la gestione degli errori nelle promise

  1. Restituire sempre o lanciare errori nei blocchi catch, per evitare che gli errori vengano ignorati silenziosamente.
  2. Concatenare correttamente le promise per assicurarsi che gli errori vengano intercettati e gestiti.
  3. Utilizzare i blocchi finally dove necessario per eseguire operazioni di pulizia, indipendentemente dall'esito della promise.

Implementazione di un blocco finally

Il metodo finally() viene utilizzato per eseguire un blocco di codice dopo che le promise si sono concluse, indipendentemente dall'esito.


javascript— editable

Gestione dei rifiuti non gestiti

Se una promise viene rifiutata e nessun .catch() la gestisce, l'errore viene perso silenziosamente — non esiste un try/catch circostante come nel codice sincrono. Per evitare che i bug spariscano, l'ambiente genera un evento globale unhandledrejection a cui è possibile mettersi in ascolto. Si tratta di una rete di sicurezza di ultimo ricorso per il logging e la segnalazione, non di un sostituto di un vero .catch().

Nel browser:


javascript— editable

In Node.js l'equivalente è process.on('unhandledrejection', (reason) => { ... }).

Gestione degli errori con async/await

async/await è basato sulle promise, quindi gli stessi rifiuti si verificano — ma vengono intercettati con un normale blocco try/catch, che si legge come codice sincrono. Un await su una promise rifiutata genera un'eccezione all'interno della funzione async, e try/catch la intercetta. Vedi JavaScript: async/await per il quadro completo.


javascript— editable
Informazione

Un try/catch all'interno di una funzione async intercetta solo gli errori delle promise su cui si usa await. Se si chiama una funzione che restituisce una promise senza await, il suo rifiuto sfugge al try/catch — è necessario usare await oppure collegare un .catch().

Conclusione

Una gestione efficace degli errori nelle promise JavaScript è essenziale per sviluppare applicazioni web affidabili e resilienti. Comprendendo il metodo .catch(), il secondo argomento di .then(), la propagazione del rifiuto, il rilancio e il hook di pulizia .finally(), gli sviluppatori possono garantire che le loro applicazioni gestiscano gli errori asincroni in modo elegante e si riprendano senza andare in crash. Quando si lavora con async/await, racchiudere le chiamate di promise in attesa in blocchi try/catch per una gestione degli errori dall'aspetto sincrono, e mantenere un listener globale unhandledrejection come rete di sicurezza per i casi che si perdono.

Per approfondire, continua con Concatenamento delle promise e la Promise API.

Esercitazione

Pratica
Qual è il concetto chiave da comprendere sulla gestione degli errori nelle promise JavaScript?
Qual è il concetto chiave da comprendere sulla gestione degli errori nelle promise JavaScript?
Was this page helpful?