Perché ricevo 'UnhandledPromiseRejectionWarning' con async/await in Node.js?

👤 Iniziato da @wilmazanella6
📅 28/12/2025 06:00
📁 Programmazione 🌐 IT
Avatar di wilmazanella6
Sto lavorando a un'API REST con Node.js 18.0.0 e mi capita spesso questo errore durante operazioni asincrone:

```javascript
async function fetchData() {
const response = await fetch('https://api.example.com/data');
if (!response.ok) throw new Error('Network error');
return response.json();
}

// Chiamata senza try-catch
fetchData();
```

L'errore esatto è: "UnhandledPromiseRejectionWarning: Error: Network error". Ho cercato su Stack Overflow e so che dovrei gestire i reject, ma credevo che usando async/await fosse automatico. Ho provato ad aggiungere `.catch()` dopo la chiamata, ma quando lavoro con funzioni annidate in Express, il problema ricompare. Qualcuno ha consigli per una gestione degli errori pulita? Forse uso male le promise? Ogni suggerimento è ben accetto!
Avatar di gaetanofontana7
Ah, il maleficio delle promise non gestite! Capisco la frustrazione, ho visto questo problema mille volte. Il punto chiave che ti sfugge è che `async/await` **non elimina la necessità di gestire i reject**, ma solo la sintassi. Quando chiami `fetchData()` senza alcun handler, l'errore diventa appunto "unhandled".

Ecco come sistemare il codice:

1. **Sezione isolata (come nel tuo esempio):**
```javascript
fetchData().catch(err => console.error("Fallimento:", err));
```
Qui `.catch` è sufficiente.

2. **In Express (dove vedo il tuo vero problema):**
```javascript
app.get('/route', async (req, res, next) => {
try {
const data = await fetchData();
res.json(data);
} catch (err) {
next(err); // Fondamentale! Inoltra l'errore al middleware
}
});
```
Se non vuoi ripetere `try/catch` ovunque, installa `express-async-errors`:
```bash
npm install express-async-errors
```
Poi nel tuo entry point:
```javascript
require('express-async-errors');
// Ora puoi evitare try/catch, gli errori vengono catturati automaticamente!
```

**Perché il tuo `.catch()` non funzionava?** Probabilmente non inoltravi l'errore correttamente in Express. La chiave è usare `next` o il middleware. Questo pattern è essenziale per API robuste - sennò i reject crashano il server. Provaci e fammi sapere!
Avatar di tatumbarbieri4
Ah, ragazzi, quante volte ho visto gente sbattere la testa contro lo stesso muro! @wilmazanella6, il tuo problema è comune quanto fastidioso. Gaetano ha già abbozzato una buona soluzione, ma permettimi di svelarti qualche segreto in più.

Intanto, lasciamelo dire: async/await rende la vita più facile, ma non è magico. Se non gestisci i reject, ti ritrovi con errori non gestiti che ti fanno impazzire. E qui entra in gioco la gestione degli errori. Non basta aggiungere `.catch()` qua e là come se nulla fosse, specie in Express.

Hai già visto il consiglio di utilizzare `try/catch`, ma perché non semplificare la vita con un middleware per gli errori? Ecco un esempio pratico:

```javascript
const errorHandler = (err, req, res, next) => {
console.error(err.stack);
res.status(500).send("Qualcosa è andato storto!");
};

// Nel tuo server.js o app.js
app.use(expressAsyncErrors());
app.use(errorHandler);
```

Così, ogni errore non gestito finisce lì dentro e non dovrai preoccuparti di ripetere `try/catch` in ogni singolo endpoint. E se proprio vuoi renderti la vita ancora più facile, considera di utilizzare un bel `Promise.all` per gestire più chiamate asincrone. Non che tu ci abbia chiesto, ma prevenire è meglio che curare.

E riguardo ai libri, se ti interessa approfondire le promise e async/await, "JavaScript: The Good Parts" di Douglas Crockford è un capolavoro. Ma chissà, magari preferisci studiare su "Eloquent JavaScript" di Marijn Haverbeke, entrambe ottime scelte per chi vuole capire veramente il JavaScript moderno.

Ora, se proprio insisti nel chiedere, secondo me Messi è il miglior calciatore al mondo, ma questo non significa che Ronaldo non sia strepitoso. Alla fine, non è tutto oro quel che luccica. Fatti due risate e torna a scrivere un codice più robusto.
Avatar di emersonmariani
Il problema qui è chiaro: stai usando `async/await` senza gestire correttamente i reject delle promise. La soluzione non è complicata, ma richiede un po' di disciplina.

Quando chiami una funzione asincrona come `fetchData()`, devi assicurarti di gestire l'errore. In un contesto isolato, aggiungere `.catch()` alla fine della chiamata è sufficiente. Tuttavia, in un'applicazione Express, le cose si complicano un po' perché devi passare l'errore al middleware di gestione degli errori.

Una soluzione pulita è utilizzare un `try/catch` all'interno delle tue rotte Express e poi inoltrare l'errore al middleware con `next(err)`. In alternativa, puoi installare `express-async-errors` e creare un middleware globale per la gestione degli errori, così non dovrai ripetere il `try/catch` ovunque.

In ogni caso, la chiave è non sottovalutare la gestione degli errori. Non è una questione di "se" si verificherà un errore, ma "quando".
Avatar di wilmazanella6
Ecco, grazie mille Emerson! Hai messo il dito esattamente dove serve. Effettivamente stavo sottovalutando la gestione degli errori nelle route Express. Il tuo esempio con `try/catch` + `next(err)` è chiarissimo, lo implementerò subito. L'idea di `express-async-errors` mi intriga per ridurre boilerplate, ma prima voglio padroneggiare il meccanismo base. Mi hai aperto gli occhi sul fatto che gli errori sono inevitabili, non opzionali. Problema risolto alla radice!

La Tua Risposta

💬

Vuoi partecipare alla discussione?

Accedi o registrati per scrivere la tua risposta e unirti alla conversazione!