Errori di cattura in JavaScript Promesse con un primo livello provare … catch

Quindi, voglio che il mio primo livello di cattura sia quello che gestisce l’errore. Esiste comunque la possibilità di propagare il mio errore fino alla prima presa?

Codice di riferimento, non funzionante (ancora):

Promise = require('./framework/libraries/bluebird.js'); function promise() { var promise = new Promise(function(resolve, reject) { throw('Oh no!'); }); promise.catch(function(error) { throw(error); }); } try { promise(); } // I WANT THIS CATCH TO CATCH THE ERROR THROWN IN THE PROMISE catch(error) { console.log('Caught!', error); } 

Con la nuova syntax asincrona / attendi puoi raggiungere questo objective. Si prega di notare che al momento della scrittura questo non è supportato da tutti i browser, probabilmente è necessario traspolare il codice con babel (o qualcosa di simile).

 // Because of the "async" keyword here, calling getSomeValue() // will return a promise. async function getSomeValue() { if (somethingIsNotOk) { throw new Error('uh oh'); } else { return 'Yay!'; } } async function() { try { // "await" will wait for the promise to resolve or reject // if it rejects, an error will be thrown, which you can // catch with a regular try/catch block const someValue = await getSomeValue(); doSomethingWith(someValue); } catch (error) { console.error(error); } } 

Non è ansible utilizzare le istruzioni try-catch per gestire le eccezioni generate in modo asincrono, poiché la funzione è “restituita” prima che venga generata un’eccezione. Dovresti invece usare i metodi promise.then e promise.catch , che rappresentano l’equivalente asincrono dell’istruzione try-catch.

Quello che devi fare è restituire la promise, quindi concatenare un altro .catch ad esso:

 function promise() { var promise = new Promise(function(resolve, reject) { throw('Oh no!'); }); return promise.catch(function(error) { throw(error); }); } promise().catch(function(error) { console.log('Caught!', error); }); 

Le promesse sono concatenabili, quindi se una promise ripresenta un errore, sarà delegata alla successiva .catch .

A proposito, non è necessario utilizzare le parentesi attorno alle istruzioni di throw a (il throw a è uguale a quello di throw(a) ).


Se stai eseguendo questo codice in Node.js e per qualche motivo non sei autorizzato a modificare la funzione promise , puoi utilizzare i domini per farlo. Tieni presente che i domini non sono esattamente le più facili da gestire e presentano alcuni fastidiosi casi limite in determinate circostanze. A meno che tu non sia realmente necessario, ti consiglio vivamente di usare le promesse.

No! Questo è completamente imansible, poiché le promesse sono intrinsecamente asincrone. La clausola try-catch avrà terminato l’esecuzione quando viene lanciata l’eccezione (e il viaggio nel tempo non sarà ancora stato inventato).

Invece, restituisci le promesse da tutte le tue funzioni e aggancia un gestore degli errori su di esse.

Spesso trovo la necessità di garantire che venga restituita una Promessa e quasi altrettanto spesso la necessità di gestire un errore locale e quindi di riconsiderarlo.

 function doSomeWork() { return Promise.try(function() { return request.get(url).then(function(response) { // ... do some specific work }); }).catch(function(err) { console.log("Some specific work failed", err); throw err; // IMPORTANT! throw unless you intend to suppress the error }); } 

Il vantaggio di questa tecnica (Promise.try / catch) è che si avvia / si assicura una catena di promise senza i requisiti di risoluzione / rifiuto che possono essere facilmente persi e creare un incubo di debug.

Per espandere la risposta di edo , se si desidera rilevare gli errori di una funzione asincrona che non si desidera attendere. Puoi aggiungere una dichiarazione di attesa alla fine della tua funzione.

 async function() { try { const asyncResult = someAsyncAction(); // "await" will wait for the promise to resolve or reject // if it rejects, an error will be thrown, which you can // catch with a regular try/catch block const someValue = await getSomeValue(); doSomethingWith(someValue); await asyncResult; } catch (error) { console.error(error); } } 

Se someAsyncAction fallisce, l’istruzione catch lo gestirà.