Manipulação de exceção assíncrona com promises bluebird

Qual é a melhor maneira de lidar com esse cenário? Eu estou em um ambiente controlado e não quero falhar.

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); }); 

Ao jogar de dentro do setTimeout sempre teremos:

 $ 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 o lançamento ocorrer antes do setTimeout, então os bluebirds pegarão:

 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); }); 

Resulta em:

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

O que é ótimo – mas como alguém lidaria com um retorno de chamada asynchronous desonesto dessa natureza no nó ou no navegador.

As promises não são domínios , elas não capturam exceções de retornos de chamada asynchronouss. Você simplesmente não pode fazer isso.

As promises, no entanto, capturam exceções que são lançadas de dentro de um retorno de chamada do construtor then / catch / Promise . Então use

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

(ou apenas Promise.delay ) para obter o comportamento desejado. Nunca jogue em callbacks asynchronouss personalizados (não prometidos), rejeite sempre a promise circundante. Use try-catch se realmente precisar ser.

Obrigado @Bergi. Agora eu sei promise não pega erro no retorno de chamada assíncrona. Aqui estão os meus 3 exemplos que testei.

Nota: Após a rejeição de chamadas, a function continuará em execução.

Exemplo 1: rejeitar e, em seguida, lançar o erro no callback do construtor de promise

Exemplo 2: rejeitar e, em seguida, lançar erro no retorno de chamada asynchronous setTimeout

Exemplo 3: rejeitar e, em seguida, retornar no retorno de chamada asynchronous setTimeout para evitar falhas

 // 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); });