2016-04-06 421 views
1

我在藍鳥承諾中拋出一個錯誤的問題。請採取以下代碼:藍鳥承諾和域名

var Promise = require('bluebird'); 
var domain = require('domain'); 

var problem = function() { 
    return new Promise(function(resolve, reject){ 
     reject(new Error('Oops!')); 
    }); 
}; 

domain.create() 
    .on('error', function(e){ 
     console.log("Caught Error " + e.message) 
     process.exit(1); 
    }) 
    .run(function() { 
     problem().done(); 
    }); 

我期望在控制檯中看到Caught Error Oops!。但是,似乎錯誤沒有被捕獲到域內,我在控制檯中看到一個致命的錯誤和堆棧跟蹤。

有誰知道爲什麼?

+1

域已棄用,您不應該使用它們。 –

+0

這不是很有幫助。是的,我明白域名可能會在未來被替換,但是在要求棄用它們兩年之後的今天,它們仍然是核心。由於沒有任何物品可以替代它們提供的特定功能,因此域仍處於待棄用狀態。 –

+0

這是藍鳥的問題,Q庫函數的預期如預期。 –

回答

1

藍鳥實際上正在處理異常。 Promise拒絕與未處理的異常不同。如果您在setTimeout內部創建一個真正的未處理的異常,那麼Bluebird將不會處理它,因爲它將位於不同的堆棧上,您的域將按預期工作。

var Promise = require('bluebird'); 
var domain = require('domain'); 

var problem = function() { 
    return new Promise(function(resolve, reject){ 
     setTimeout(function() { 
      throw new Error('boom!'); 
     }, 1) 

    }); 
}; 

domain.create() 
    .on('error', function(e){ 
     console.log("Caught Error " + e.message) 
     process.exit(1); 
    }) 
    .run(function() { 
     problem().done(); 
    }); 
+0

很好的答案。這無疑更好地使用process.nextTick? –

+0

process.nextTick可能會更好,我忘記了setTimeout和nextTick之間的細微差別 –