Gestione asincrona delle eccezioni con promesse bluebird

Qual è il modo migliore per gestire questo scenario. Sono in un ambiente controllato e non voglio andare in crash.

var Promise = require('bluebird'); function getPromise(){ return new Promise(function(done, reject){ setTimeout(function(){ throw new Error("AJAJAJA"); }, 500); }); } var p = getPromise(); p.then(function(){ console.log("Yay"); }).error(function(e){ console.log("Rejected",e); }).catch(Error, function(e){ console.log("Error",e); }).catch(function(e){ console.log("Unknown", e); }); 

Quando lanciamo dall’interno del setTimeout otterremo sempre:

 $ node bluebird.js c:\blp\rplus\bbcode\scratchboard\bluebird.js:6 throw new Error("AJAJAJA"); ^ Error: AJAJAJA at null._onTimeout (c:\blp\rplus\bbcode\scratchboard\bluebird.js:6:23) at Timer.listOnTimeout [as ontimeout] (timers.js:110:15) 

Se il lancio avviene prima del setTimeout, allora i bluebirds catch lo prenderanno:

 var Promise = require('bluebird'); function getPromise(){ return new Promise(function(done, reject){ throw new Error("Oh no!"); setTimeout(function(){ console.log("hihihihi") }, 500); }); } var p = getPromise(); p.then(function(){ console.log("Yay"); }).error(function(e){ console.log("Rejected",e); }).catch(Error, function(e){ console.log("Error",e); }).catch(function(e){ console.log("Unknown", e); }); 

Risultati in:

 $ node bluebird.js Error [Error: Oh no!] 

Il che è fantastico, ma come si gestirà un callback asincrona canaglia di questa natura nel nodo o nel browser.

Le promesse non sono domini , non cattureranno eccezioni da callback asincroni. Non puoi farlo.

Le promesse tuttavia catturano le eccezioni generate da un callback del costruttore then / catch / Promise . Quindi usa

 function getPromise(){ return new Promise(function(done, reject){ setTimeout(done, 500); }).then(function() { console.log("hihihihi"); throw new Error("Oh no!"); }); } 

(o solo Promise.delay ) per ottenere il comportamento desiderato. Non inserire mai richiami asincroni personalizzati (non promessi), rifiutare sempre la promise circostante. Usa try-catch se davvero deve essere.

Grazie a @Bergi. Ora so che la promise non cattura l’errore nel callback asincrono. Ecco i miei 3 esempi che ho provato.

Nota: dopo il rifiuto della chiamata, la funzione continuerà a funzionare.

Esempio 1: rifiutare, quindi generare un errore nel callback del costruttore della promise

Esempio 2: rifiutare, quindi generare un errore nel callback async setTimeout

Esempio 3: rifiutare, quindi tornare nel callback async setTimeout per evitare arresti anomali

 // Caught // only error 1 is sent // error 2 is reached but not send reject again new Promise((resolve, reject) => { reject("error 1"); // Send reject console.log("Continue"); // Print throw new Error("error 2"); // Nothing happen }) .then(() => {}) .catch(err => { console.log("Error", err); }); // Uncaught // error due to throw new Error() in setTimeout async callback // solution: return after reject new Promise((resolve, reject) => { setTimeout(() => { reject("error 1"); // Send reject console.log("Continue"); // Print throw new Error("error 2"); // Did run and cause Uncaught error }, 0); }) .then(data => {}) .catch(err => { console.log("Error", err); }); // Caught // Only error 1 is sent // error 2 cannot be reached but can cause potential uncaught error if err = null new Promise((resolve, reject) => { setTimeout(() => { const err = "error 1"; if (err) { reject(err); // Send reject console.log("Continue"); // Did print return; } throw new Error("error 2"); // Potential Uncaught error if err = null }, 0); }) .then(data => {}) .catch(err => { console.log("Error", err); });