如何确定在Node.js中导致UnhandledPromiseRejectionWarning的原因?

我已经在asynchronous/等待库的基础上构build了Node.js应用程序,并且在大多数情况下工作得很好。 我遇到的唯一麻烦是,只要承诺没有完成,我就会得到以下错误的一些变化:

(node:83333) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): TypeError: Cannot read property '_id' of null 

我无意中能够find违规的承诺,但有时需要进行相当多的debugging。 有没有一种方法可以用来检查未处理的承诺的行号? 会救我很大的头痛。

我build议你在入口文件的开头设置一个全局的unhandledRejection处理程序 :

 process.on('unhandledRejection', (reason, p) => { throw reason }); 

这样,即使您忘记在本地捕捉错误,您仍然可以轻松地追踪它们。

更新

似乎有一些混淆,如何上述处理程序可以帮助你。 基本上,当你没有发现诺言错误时,节点向控制台输出警告。 无论什么愚蠢的原因,节点只输出没有堆栈的错误信息。 设置处理程序,然后重新抛出错误将生成堆栈,并允许您更轻松地debugging代码。 这是一个例子:

 let test = () => new Promise((resolve, reject) => { throw new Error('Random Error'); // same as "reject(new Error('Random Error'));" }); test(); 

没有处理程序,你会得到:

 (node:20012) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Random Error 

然后,我们在我们的文件顶部添加处理程序:

 process.on('unhandledRejection', (reason, p) => { throw reason }); let test = () => new Promise((resolve, reject) => { throw new Error('Random Error'); // same as "reject(new Error('Random Error'));" }); test(); 

现在我们得到一个更好的错误堆栈:

 (function (exports, require, module, __filename, __dirname) { process.on('unhandledRejection', (reason, p) => { throw reason }); ^ Error: Random Error at Promise (S:\amir\test.js:5:9) at test (S:\amir\test.js:3:18) at Object.<anonymous> (S:\amir\test.js:8:1) at Module._compile (module.js:570:32) at Object.Module._extensions..js (module.js:579:10) at Module.load (module.js:487:32) at tryModuleLoad (module.js:446:12) at Function.Module._load (module.js:438:3) at Module.runMain (module.js:604:10) at run (bootstrap_node.js:394:7) 

警告是由于您的某个承诺发生了错误而引起的,但是您没有处理这个错误,这意味着您的承诺不会像您正在处理的那样处理catch

只是一个很好的做法来处理承诺,以及你正在做的事情,所以不pipe你需要记住什么样的情况,即使你100%确信这个承诺也不会导致错误。

这将给你一个更好更快的方式来debugging任何问题….所以任何承诺只是处理catch例子

 promise.then((result)=>{ //Do something here } , (error) =>{ //Handle promise rejection }).catch((err) => { //Handle error here, lets say for example, this promise is just updating user //console.log("update user error") //console.log(err); to be able to understand what is the error }) 

所以,如果你用上面的方式来处理任何承诺…你将能够知道你的错误到底在哪里…

还有一件事,我通常做的是console.log什么诺言是在console.log之前做的错误,正如你可以看到在上面的代码我正在考虑这个承诺只是更新用户…所以我提到捕捉“更新用户错误”

现在你知道这个错误是在更新用户的承诺