【问题标题】:NodeJS crash: Mongoose findById() does NOT throw error when document is NOT foundNodeJS 崩溃:未找到文档时,Mongoose findById() 不会抛出错误
【发布时间】:2016-09-11 01:57:12
【问题描述】:

我试图研究这个问题的原因;这很可能是我对 Mongoose 工作方式的误解。我正在尝试以 REST 样式创建 CRUD 后端。 GET、PUT、POST 似乎都有效。但是,对于 DELETE 动词的问题,我有点不知所措。

问题

我用 Postman 将一些假数据输入到 mongo 中,一切顺利。所以我复制了一条记录的_id 字段并尝试删除。当我发送 DELETE 请求时,成功消息传来,记录确实从 mongo 中删除。但是,在删除其他记录之后,我决定尝试删除一条我已经删除的文档的_id 记录。

我向“api/brothers/57280602953cff031f21ad9c”发送了一个删除请求

原来 NodeJS 崩溃了!

这是相关的服务器代码:

// DELETE a brother by id
app.delete('/api/brothers/:id', function(req, res) {

    Brother.findById(req.params.id, function(err, brother) {

      if (err) {
        // error finding brother
        res.json(err);

      } else {

        // remove record
        brother.remove(function(err, brother) {

          if (err) {
            // error removing!
            res.send(err);
          } else {

            // successful DELETE!
            res.json({
              message : "successfully deleted",
              brother : brother
            });
          }

        });
      }

    });


  });

Nodejs 崩溃,我的控制台窗口返回以下内容:

TypeError: Cannot read property 'remove' of null
[nodemon] app crashed - waiting for file changes before starting...

为什么 Mongoose 没有抛出错误?

据我了解,没有引发错误,因为如果引发错误,我的 if 语句将执行并将错误返回给用户。如果我在 url 中输入了一个虚假的 id,那么我会返回一个错误,但如果我粘贴一个已删除记录的 _id,则不会引发错误,并且执行会转到 else 块,然后继续删除不存在的文档。甚至.remove() 似乎都没有发现错误......服务器只是崩溃了。

所以...我的问题是为什么?是否与 Mongo 投射 _id 有关?为什么不抛出错误?服务器为什么会崩溃。

某种解决方案...

如果我修改if 语句,不仅要捕获错误,还要检查从findById() 函数返回的brother 是否存在,错误会返回给用户,灾难是避免:

if (err || !brother) {
  // THIS WORKS
  res.json(brother);

 } else { ...

再次...为什么?为什么如果 brother obj 为 null,Mongoose 甚至会尝试删除文档?服务器为什么会崩溃?

// 我使用的是 Express 4.13.4 和 Mongoose 4.4.12

感谢您的帮助,请原谅任何新手的无知。

【问题讨论】:

    标签: node.js mongodb express mongoose crash


    【解决方案1】:

    在使用remove之前,你必须检查兄弟是否存在,如果找不到项目,moongoose不会返回错误。

    if(!brother){
       return res.status(400).send('Item Not Found')   
    }
    

    【讨论】:

    • 嗯...有趣。你有关于 remove() 和填充回调参数的 Mongoose 文档的链接吗?我在发帖前尝试过查找,但找不到任何东西
    【解决方案2】:

    err 会在发生无法连接到数据库、身份验证无效等事件时抛出。但是对于查询,只要查询正确,它就会抛出任何错误。在您的查询返回0 行的情况下,它只会使用null 调用您的回调,因此您可能需要在使用brother 之前进行检查。

    【讨论】:

      【解决方案3】:

      你得到的是一个 Javascript 错误而不是 Mongoose 错误,你试图在 null 上调用一个方法。 foo = null; foo.bar(); 产生同样的错误。

      找0个文件不是错误,执行了找的动作却找到了0个东西。

      Mongoose有一个辅助函数findOneAndRemove,你应该使用它,少写代码,少麻烦:

      app.delete('/api/brothers/:id', function(req, res) {
          Brother.findOneAndRemove({ _id: req.params.id }, function(err, brother, res) {
      
          });
      });
      

      【讨论】:

      • 哦,我明白了。这很有趣......为什么如果我在 url 中输入一个虚假的字符串,比如“hahdhd”,那么我会返回 null。但是,如果我输入任何类似于 mongo ID 的内容,mongoose 会尝试在 null 上调用 remove()?
      • @user96872 我不知道,你应该用 console.log 跟踪它以知道哪个res.send()/json() 正在发送空响应。
      猜你喜欢
      • 2015-01-04
      • 2021-04-09
      • 2019-07-14
      • 2017-05-16
      • 2018-03-15
      • 2023-01-03
      • 1970-01-01
      • 2019-07-15
      • 1970-01-01
      相关资源
      最近更新 更多