为啥即使我有一个 catch() 函数,我也会收到 UnhandledPromiseRejectionWarning?

Posted

技术标签:

【中文标题】为啥即使我有一个 catch() 函数,我也会收到 UnhandledPromiseRejectionWarning?【英文标题】:Why do I get an UnhandledPromiseRejectionWarning even though I have a catch() function?为什么即使我有一个 catch() 函数,我也会收到 UnhandledPromiseRejectionWarning? 【发布时间】:2018-04-10 11:21:48 【问题描述】:

我正在尝试使用以下代码将用户保存到我的数据库中:

userRoutes.post('/signup', (req, res) => 
    if (req.session.user) req.session.destroy();

    const user = new User(req.body);

    user.save()
    .then(savedUser => 
        req.session.user = savedUser._id;

        res.status(200).json(
            success: true,
            data: 
                firstName: savedUser.firstName,
                lastName: savedUser.lastName,
                username: savedUser.username,
                email: savedUser.email,
                dateCreated: savedUser.dataCreated,
                _id: savedUser._id
            ,
        );
    )
   .catch(error => 
        res.status(500).json(
            success: false,
            error
        );
    );
);

但我仍然收到此错误:UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: cb is not a function

我正在使用猫鼬来保存文档。

【问题讨论】:

res 在哪里定义?我希望它是一个从 promise 返回的对象,并在 then() 函数中声明为参数。我错过了什么吗? 整个事情都在定义 res 的快速路线中,但这不是问题,所以我不想用更多的代码行来混乱帖子。 你能添加完整的错误堆栈吗? TypeError: cb is not a function - 我认为错误不在此代码中 您使用的是哪个会话存储?是connect-mongo吗? 【参考方案1】:

我从来没有使用过connect-mongo,我自己也没有安装 Mongo 来尝试一下,但我确实快速浏览了源代码,看看我是否可以解释你遇到的问题。

最新版本 (2.0.0) 似乎是 3 周前发布的。我相信该版本中包含此更改:

https://github.com/jdesboeufs/connect-mongo/commit/a8b0fd49368cfc1ea634d4245105e706d2dd98c9

这改变了它调用回调的方式。

destroy的处理在这里:

https://github.com/jdesboeufs/connect-mongo/blob/509c8732061b7786857f6b835f547980c1d81c7f/src/index.js#L292

然后这会调用withCallback,这里是:

https://github.com/jdesboeufs/connect-mongo/blob/509c8732061b7786857f6b835f547980c1d81c7f/src/index.js#L5

我可能完全错了,但这似乎完全符合您的症状。调用了一个名为cb 的函数,它没有先检查它是否未定义。

一个简单的测试是将回调函数传递给destroy。这不应该是必需的,我相信这是connect-mongo 中的一个错误,但它应该有助于确认这确实是您所看到的错误的根源。您可以通过将调试器(例如 Chrome 开发工具)附加到您的节点并单步执行直到遇到错误来进一步诊断。

如果这确实是问题所在,那么我建议使用connect-mongo 提交错误报告。快速浏览一些其他会话存储的源代码,在尝试调用它之前检查回调是否未定义似乎是标准做法。

我要补充一点,我不认为destroy 是你应该在这里使用的方法。我怀疑你想要regenerate。但是我认为这是一个单独的问题,而不是导致您当前错误的原因。

我还要注意,虽然我声明不需要将回调传递给 destroyregenerate 等,但它仍然是一个好主意,因为您应该真正等待它完成 (或可能失败),然后再继续。

【讨论】:

谢谢,我对会话只有模糊的理解,所以我只是从某个地方复制了 req.session.destroy 并没有停下来意识到它可能是异步的

以上是关于为啥即使我有一个 catch() 函数,我也会收到 UnhandledPromiseRejectionWarning?的主要内容,如果未能解决你的问题,请参考以下文章

为啥即使实现了 Iterable,我也会收到 foreach 编译器错误?

为啥即使我使用 sparse_categorical_crossentrpy,我也会收到“收到超出 [0, 1) 有效范围的标签值 6”?

为啥即使在包含 math.h 并使用 -lm 链接到数学库之后我也会收到“未定义的符号:.sqrtf”

为啥即使我 .catch() Promise.all() 也会抛出异常?

为啥即使我修改了 lock 变量,我也会得到一个无限的 while 循环? [复制]

为啥即使存在列,我也会有 ORA-00904?