nodejs域是处理nodejs中错误的最新方法。域可以捕获错误/其他事件以及传统抛出的对象。域还提供了处理回调的功能,其中错误通过intercept方法作为第一个参数传递。
与正常的try/catch风格的错误处理一样,通常最好在错误发生时抛出错误,并将您希望隔离错误的区域排除在外,以免影响代码的其余部分。“屏蔽”这些区域的方法是调用domain.run,将一个函数作为隔离代码块。
在同步代码中,以上内容就足够了——当发生错误时,要么让它被抛出,要么抓住它并在那里处理,还原需要还原的任何数据。
try {
//something
} catch(e) {
// handle data reversion
// probably log too
}
当错误发生在异步回调中时,您要么需要能够完全处理数据的回滚(共享状态、数据库等外部数据)。或者,您必须设置一些东西来指示发生了异常——如果您关心该标志,则必须等待回调完成。
var err = null;
var d = require('domain').create();
d.on('error', function(e) {
err = e;
// any additional error handling
}
d.run(function() { Fiber(function() {
// do stuff
var future = somethingAsynchronous();
// more stuff
future.wait(); // here we care about the error
if(err != null) {
// handle data reversion
// probably log too
}
})});
上面的一些代码很难看,但您可以为自己创建模式以使其更漂亮,例如:
var specialDomain = specialDomain(function() {
// do stuff
var future = somethingAsynchronous();
// more stuff
future.wait(); // here we care about the error
if(specialDomain.error()) {
// handle data reversion
// probably log too
}
}, function() { // "catch"
// any additional error handling
});
更新(2013-09):
上面,我使用了一个未来,它暗示了纤维语义,允许您在线等待未来。这实际上允许你在所有事情上使用传统的try-catch块,我认为这是最好的方法。然而,你不能总是这样做(即在浏览器中)。。。
还有一些未来不需要纤维语义(然后使用普通的浏览器JavaScript)。这些可以被称为期货、承诺或延期(我将从这里开始提及期货)。普通的旧JavaScript期货库允许在期货之间传播错误。只有其中的一些库允许正确处理任何抛出的未来,所以要小心。
例如:
returnsAFuture().then(function() {
console.log('1')
return doSomething() // also returns a future
}).then(function() {
console.log('2')
throw Error("oops an error was thrown")
}).then(function() {
console.log('3')
}).catch(function(exception) {
console.log('handler')
// handle the exception
}).done()
这模拟了正常的try-catch,即使片段是异步的。它将打印:
1
2
handler
请注意,它不打印“3”,因为引发了中断该流的异常。
看看蓝鸟的承诺:
https://github.com/petkaantonov/bluebird
注意,除了这些库之外,我还没有找到其他许多库可以正确处理抛出的异常。jQuery的延迟,例如,不要-“fail”处理程序永远不会让“then”处理程序抛出异常,在我看来,这是一个交易破坏者。