Sobes.tech
Junior

Come gestire un errore (rifiuto) di una promessa usando await?

sobes.tech AI

Risposta dell'AI

Quando si utilizza await con una promessa, gli errori (rifiuti) possono essere gestiti in diversi modi:

  1. Costruzione try...catch: Il metodo più comune e raccomandato. Permette di intercettare elegantemente gli errori sollevati durante la risoluzione (resolve) o il rifiuto (reject) della promessa.

    async function fetchData() {
      try {
        const response = await fetch('https://api.example.com/data');
        if (!response.ok) {
          throw new Error(`Errore HTTP! stato: ${response.status}`);
        }
        const data = await response.json();
        console.log(data);
      } catch (error) {
        console.error('Errore nel recupero dei dati:', error);
        // Gestione aggiuntiva dell'errore o notifica all'utente
      }
    }
    
    fetchData();
    
  2. Metodo .catch() dopo await: Meno preferibile, ma possibile. L'errore sarà gestito nel callback .catch(), se la promessa viene rifiutata.

    async function fetchData() {
      const response = await fetch('https://api.example.com/data')
        .catch(error => {
          console.error('Errore durante fetch:', error);
          // Gestione dell'errore fetch
          throw error; // Rilancia l'errore per ulteriori gestioni, se necessario
        });
    
      if (response && !response.ok) {
           console.error(`Errore HTTP! stato: ${response.status}`);
           // Gestione errore HTTP
      }
    
      if (response && response.ok) {
          const data = await response.json()
              .catch(error => {
                  console.error('Errore nel parsing JSON:', error);
                  // Gestione errore parsing JSON
              });
          if (data) {
              console.log(data);
          }
      }
    }
    
    fetchData();
    

    Questo approccio può diventare ingombrante quando si gestiscono molteplici punti di errore potenziali.

  3. Gestione con valore di ritorno dell'errore: Alcune librerie o funzioni proprie possono restituire una tupla [dati, errore] invece di rifiutare la promessa.

    async function safelyFetchData() {
       const [data, error] = await safePromise(fetch('https://api.example.com/data'));
       if (error) {
          console.error('Errore generale nel recupero dei dati:', error);
          return null; // O altro valore che indica fallimento
       }
       // Si assume che safePromise gestisca anche gli errori response.ok
       console.log(data);
       return data;
    }
    
    // Esempio di implementazione di safePromise (semplificato)
    async function safePromise(promise) {
        try {
            const result = await promise;
             // Qui può esserci un controllo result.ok per fetch
             if (result && result.ok !== undefined && !result.ok) {
                 throw new Error(`Errore HTTP! stato: ${result.status}`);
             }
            // Per fetch, potrebbe essere necessario await result.json()
            if (result && typeof result.json === 'function') {
                const jsonData = await result.json();
                return [jsonData, null];
            }
            return [result, null];
        } catch (error) {
            return [null, error];
        }
    }
    
    safelyFetchData();
    

    Questo pattern (spesso chiamato "error-first callback" o "gestione degli errori in stile go") è utile quando si desidera gestire gli errori localmente senza interrompere l'esecuzione della funzione.

Il metodo più pulito e leggibile è usare try...catch intorno al blocco di codice che contiene await.