带有承诺的 MongoDB 查询不执行 if 语句(MongoDB node.js 驱动程序)

Posted

技术标签:

【中文标题】带有承诺的 MongoDB 查询不执行 if 语句(MongoDB node.js 驱动程序)【英文标题】:MongoDB query with promise not executing if statement (MongoDB node.js driver) 【发布时间】:2021-06-09 23:23:17 【问题描述】:

我试图弄清楚为什么在找不到文档时不执行 if(!document),而是应用程序直接跳转到 catch 块并返回 500 状态?

为了澄清,通过 req.body.id 发送的 id 没有问题,如果我发送与数据库中的文档匹配的有效 ID,则执行成功块。问题是当我发送一个与文档不匹配的 ID 时,if (!document) 块不会被执行,而是会执行 catch 块。

我的意图是这样的(如果代码示例不够清楚的话):

如果未找到该文档,则返回: return res.status(401).json( message: 'Unauthorized.'

如果找到文档: return res.status(200).json( message: 'Authorized.' );

如果出现数据库/服务器错误: return res.status(500).json( message: 'Internal server error.' )

下面的小代码示例:

const login = (req, res) => 
    userSchema
        .findById(req.body.id)
        .then((document) => 
            if (!document) 
                return res.status(401).json( message: 'Unauthorized.' ).end();
            
            return res.status(200).json( message: 'Authorized.' );
        )
        .catch((err => return res.status(500).json( message: 'Internal server error.' );
;

【问题讨论】:

console.log(req.body.id) 紧跟在const login = (req, res) => 之后会告诉你你需要知道的一切。 旁注;从安全的角度来看,这感觉不安全。您的身份验证过程似乎仅基于传入有效用户记录 ID 的用户。用户身份验证令牌应该基于最终会过期的会话,而不是不会更改的用户记录 ID。 这只是一个简化的例子...... req.body.id 与此无关,只要发送的 id 正确,我可以毫无问题地检索电影。问题是为什么当我输入一个不正确的 id 时 if(!document) 没有被执行,而是 catch 块。 【参考方案1】:

为了成功执行这部分:

userSchema
        .findById(req.body.id)
          ...

req.body.id 必须是可转换为 ObjectId 的值。否则你会看到这个错误CastError: Cast to ObjectId failed for value...,当然会触发catch 块。

因此,例如,如果 req.body.id604156ee6db28527531bd612,完全可以转换为 ObjectId,则您的查询将实际执行,如果未找到结果,将触发您的 if 块。

但是,如果 req.body.idsh21343dfs 或空字符串,则 findById 将抛出上述 CastError 并将您发送到 catch 块中。

因此,只需使用 catch 作为提示发送回 User Not Found 错误之类的内容,因为在 findById 中几乎没有其他事情可以触发该 catch 块

或者你可以像这样明确地检查字符串的有效性:

const ObjectID = require('mongodb').ObjectID;
...
...
if(ObjectID.isValid(req.body.id))
    return res.status(401).json( message: 'Unauthorized.' ).end();

【讨论】:

非常感谢您花时间详细解释。现在一切都说得通了。 @octavemirbeau 是的。乐于助人。

以上是关于带有承诺的 MongoDB 查询不执行 if 语句(MongoDB node.js 驱动程序)的主要内容,如果未能解决你的问题,请参考以下文章

带有if和else语句的foreach循环在if语句为假时不执行else语句

使用带有 async/await 的 mongoose 承诺

带有 API 和数据库查询的 Node.js Promise Chain

Firebird 2.5 SQL 查询执行计划不使用带有 OR 语句的索引

带有 if 语句的 Oracle 数据库查询

带有 IF 语句的 PL/SQL Oracle 查询