我正在使用Cujo的伟大When库为我的Node项目提供Promises / A +实现,尽管这个问题不是特定于节点的。
通常,什么时候很棒:它让我编写更易于维护,可读的代码。
然而,当我的回调意外失败(访问空变量的属性等)时,异常被有效地吞噬了,如Promise / A +规范似乎是specified。不幸的是,这意味着我没有得到任何关于错误的反馈(除了回调在此时停止执行)。没有错误类型或消息,没有行号。
举例说明:
// hypothetical asynchronous database query
database.query(queryDetails).then(function(result) {
var silly = 3.141592654;
silly(); // TypeError: number is not a function!
process(result); // this code is silently never executed
});
我可以想到一些(不可接受的)方法来解决这个问题:
then
调用提供失败回调(将原因/异常转储到控制台)console.log('I got here 123')
我只是做错了吗?当然,我并不是唯一一个发现基于promises的代码可调试性差的人。有一个明显的解决方案我错过了吗?
答案 0 :(得分:16)
2016年9月更新:NodeJS 6.6.0+和7.0+将在未处理的拒绝时自动发出警告。使用--trace-warnings
运行节点以获得合理的堆栈跟踪。仍然不如蓝鸟给你的好,但比以前的情况好很多。
好的,所以总结评论中的信息并添加一些。
.done
方法来解决此问题,这会导致抛出未捕获的拒绝。像When和Q这样的库以这种方式解决问题。例如,如果.then
之后的.query
是.done
,那么您将获得较长的堆栈跟踪。因此:
require('when/monitor/console'); // when will now log async rejections used with
// `then` , this is experimental in when.
使用蓝鸟
Promise.longStackTraces(); // Bluebird always logs async rejections but with this
// option it will stitch the asynchronous context stack
// for you in your methods.
答案 1 :(得分:9)
以下是我如何检测Promise在Node上被拒绝但未被捕获的方式:
if (typeof process === 'object') {
process.on('unhandledRejection', (error, promise) => {
console.error("== Node detected an unhandled rejection! ==");
console.error(error.stack);
});
}
除此之外,您还可以使用此monkey wrapper to provide long stack traces for Node's ES6 Promises。它产生与Q longStackSupport
类似的输出。由于性能问题,我不建议在开发代码之外使用它。 (它在Node v4.4.1中为我工作。我还没有在Chrome或Firefox中测试它。)