【问题标题】:How can I determine what causes an UnhandledPromiseRejectionWarning in Node.js?如何确定导致 Node.js 中出现 UnhandledPromiseRejectionWarning 的原因?
【发布时间】:2018-04-08 04:59:40
【问题描述】:

我已经围绕 async/await 库构建了我的 Node.js 应用程序,并且它大部分时间都运行良好。我遇到的唯一问题是,每当未履行承诺时,我都会收到以下错误的一些变体:

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

我通常能够找到有问题的承诺,但有时需要进行大量调试。有没有一种方法可以用来检查未处理承诺的行号?会省去我很大的麻烦。

【问题讨论】:

    标签: node.js promise async-await


    【解决方案1】:

    我建议你在入口文件的最开始设置一个全局unhandledRejection handler

    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();
    

    没有你得到的处理程序:

    (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)
    

    【讨论】:

    • 但这如何帮助定位promise错误处理程序丢失的位置? OP 似乎已经记录了拒绝。
    • OP 得到的错误由节点自动记录,并且缺少完整的错误堆栈。但是,通过设置上述处理程序并抛出错误,您将获得一个完整的错误堆栈,其中包含行号和所有内容,因此有助于跟踪被拒绝的承诺。
    【解决方案2】:

    警告是由您的一个承诺中发生错误引起的,但您没有处理它,这意味着您的承诺没有处理 catch 以及您正在处理 then

    处理promise catch 以及处理then 只是一个好习惯,所以无论在什么情况下,您都需要牢记处理错误,即使您100% 确定这个promise 会不会导致错误。

    这将为您提供更好更快的方式来调试任何问题....所以对于任何承诺只需处理 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.logconsole.log 错误之前承诺正在做什么,正如您在上面的代码中看到的那样,我认为这个承诺只是更新用户......所以我在捕获“更新用户错误”中提到了

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

    【讨论】:

    • 没错,完全没有想到这个。我会尽快接受答复。
    猜你喜欢
    • 2014-01-17
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    相关资源
    最近更新 更多