尝试在 nodejs 上的异步承诺链上使用未定义变量时,控制台或日志中没有未捕获的异常
no uncaughtException in console or logs when attempting to use an undefined variable on asynchronous promise chain on nodejs
我注意到一些非常奇怪的事情:
在异步承诺链上,当我错误地尝试记录一个不存在的变量时,它创建了一个我在控制台中看不到的异常。
当我以同步方式调用完全相同的函数时(直接从方法调用它,而不是作为已解决的承诺链的结果异步激活它)它显示了预期的错误(参见下面的堆栈跟踪异常) .
这让我抓狂,因为 promise 链激活了方法(我可以看到它开始通过我在其开头添加的日志行做事),但随后它到达了有问题的日志行,从而停止了整个方法从实现其目标,但没有打印错误,也没有看到堆栈跟踪。
这使得整个调试问题变得相当复杂,我确定我在这里做错了什么。但它是什么?
这是我使用的代码:(我标记了写得不好的变量)
module.exports = {
sync: function(){
console.log(doesNotExist); // error logs
},
async: function(){
Q().then(function(){ // actually from an API returning a promise
console.log(doesNotExist); // no error in log or `unhandledException` process event
});
}
};
更新:
使用本杰明的解决方案后
process.on("unhandledRejection", function(r, e){
console.log("Oh No! Unhandled rejection!! \nr::", r,"\ne::", e);
});
情况好多了。现在我得到一些日志打印,看起来像这样
Oh No! Unhandled rejection!!
r:: [ReferenceError: Resolved123PasswordHash is not defined]
e:: { state: 'rejected',reason: [ReferenceError: Resolved123PasswordHash is not defined] }
但我仍然没有像在同步方法调用中那样得到实际的堆栈跟踪。
这是我在没有承诺链的情况下直接调用方法时的样子:
2015-07-05T18:22:51.405Z :: [ error ] :: uncaughtException: Resolved123PasswordHash is not defined["ReferenceError: Resolved123PasswordHash is not defined",
" at addUserAfterHashResolved (I:\iBitch\services\userServices.js:19:77)",
" at Object.module.exports.addUser (I:\iBitch\services\userServices.js:22:3)",
" at Object.<anonymous> (I:\iBitch\ikuter.js:263:14)",
" at Module._compile (module.js:460:26)",
" at Object.Module._extensions..js (module.js:478:10)",
" at Module.load (module.js:355:32)",
" at Function.Module._load (module.js:310:12)",
" at Function.Module.runMain (module.js:501:10)",
" at startup (node.js:129:16)",
" at node.js:814:3"]
是否有可能在使用异步承诺时获得完整的堆栈跟踪?
因为错误消息很好,但它仍然没有将我定向到特定的代码行,所以我可以知道我应该修复什么。
又一次编辑::
我发现如果我在承诺链的末尾使用“.done()”,它会显示堆栈跟踪,但随后它会使整个应用程序崩溃(这也是不受欢迎的行为)
也许这就是我需要采取的方向,但稍微修改一下?
我知道如果我开始将每个承诺链放在 try/catch 下,它将严重影响性能,所以显然不是这里的补充解决方案...
无论如何,我们将提供任何进一步的帮助。
假设您使用的是 Q 1.3+,您正在寻找 unhandledRejection
而不是 uncaughtException
:
process.on("unhandledRejection", function(r, e){
console.log("Oh No! Unhandled rejection!!", r, e);
});
在 1.3 之前,Q 中不存在此功能。其他库(如 bluebird)多年来一直内置此功能。
promise 以这种方式运行的原因是您将来可能仍会附加一个 .catch
处理程序来处理错误。流程事件假设如果你没有在事件循环中附加 .catch
轮流你永远不会(合理的 IMO)。
我注意到一些非常奇怪的事情:
在异步承诺链上,当我错误地尝试记录一个不存在的变量时,它创建了一个我在控制台中看不到的异常。
当我以同步方式调用完全相同的函数时(直接从方法调用它,而不是作为已解决的承诺链的结果异步激活它)它显示了预期的错误(参见下面的堆栈跟踪异常) .
这让我抓狂,因为 promise 链激活了方法(我可以看到它开始通过我在其开头添加的日志行做事),但随后它到达了有问题的日志行,从而停止了整个方法从实现其目标,但没有打印错误,也没有看到堆栈跟踪。
这使得整个调试问题变得相当复杂,我确定我在这里做错了什么。但它是什么?
这是我使用的代码:(我标记了写得不好的变量)
module.exports = {
sync: function(){
console.log(doesNotExist); // error logs
},
async: function(){
Q().then(function(){ // actually from an API returning a promise
console.log(doesNotExist); // no error in log or `unhandledException` process event
});
}
};
更新: 使用本杰明的解决方案后
process.on("unhandledRejection", function(r, e){
console.log("Oh No! Unhandled rejection!! \nr::", r,"\ne::", e);
});
情况好多了。现在我得到一些日志打印,看起来像这样
Oh No! Unhandled rejection!!
r:: [ReferenceError: Resolved123PasswordHash is not defined]
e:: { state: 'rejected',reason: [ReferenceError: Resolved123PasswordHash is not defined] }
但我仍然没有像在同步方法调用中那样得到实际的堆栈跟踪。
这是我在没有承诺链的情况下直接调用方法时的样子:
2015-07-05T18:22:51.405Z :: [ error ] :: uncaughtException: Resolved123PasswordHash is not defined["ReferenceError: Resolved123PasswordHash is not defined",
" at addUserAfterHashResolved (I:\iBitch\services\userServices.js:19:77)",
" at Object.module.exports.addUser (I:\iBitch\services\userServices.js:22:3)",
" at Object.<anonymous> (I:\iBitch\ikuter.js:263:14)",
" at Module._compile (module.js:460:26)",
" at Object.Module._extensions..js (module.js:478:10)",
" at Module.load (module.js:355:32)",
" at Function.Module._load (module.js:310:12)",
" at Function.Module.runMain (module.js:501:10)",
" at startup (node.js:129:16)",
" at node.js:814:3"]
是否有可能在使用异步承诺时获得完整的堆栈跟踪?
因为错误消息很好,但它仍然没有将我定向到特定的代码行,所以我可以知道我应该修复什么。
又一次编辑:: 我发现如果我在承诺链的末尾使用“.done()”,它会显示堆栈跟踪,但随后它会使整个应用程序崩溃(这也是不受欢迎的行为) 也许这就是我需要采取的方向,但稍微修改一下? 我知道如果我开始将每个承诺链放在 try/catch 下,它将严重影响性能,所以显然不是这里的补充解决方案...
无论如何,我们将提供任何进一步的帮助。
假设您使用的是 Q 1.3+,您正在寻找 unhandledRejection
而不是 uncaughtException
:
process.on("unhandledRejection", function(r, e){
console.log("Oh No! Unhandled rejection!!", r, e);
});
在 1.3 之前,Q 中不存在此功能。其他库(如 bluebird)多年来一直内置此功能。
promise 以这种方式运行的原因是您将来可能仍会附加一个 .catch
处理程序来处理错误。流程事件假设如果你没有在事件循环中附加 .catch
轮流你永远不会(合理的 IMO)。