NodeJS崩溃:当找不到文档时,Mongoose findById()不会抛出错误

我试图研究这个问题的原因。 这很可能是我对Mongoose工作方式的一个误解。 我正在试验用REST风格创build一个CRUD后端。 GET,PUT,POST都似乎工作。 不过,对于DELETE动词的问题,我有点不知所措。

问题

我用邮差input了一些伪造的数据,一切进展顺利。 所以我复制了一个我的logging的_id字段,试图删除。 当我发送DELETE请求时,成功消息传出,logging确实从mongo中删除。 但是,在删除其他logging之后,我决定尝试用已删除文档的_id删除logging。

我发送了一个DELETE请求到'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抛出if语句将执行并将错误返回给用户。 如果我在url中input了一个伪造的id,那么我得到一个错误,但是如果我粘贴了一个已经被删除的logging的_id,就不会抛出一个错误,并且执行移动到else块,然后继续移除不存在的文件。 甚至没有.remove()似乎赶上错误…服务器只是崩溃。

所以…我的问题是为什么? 这是否与蒙牛铸造_id ? 为什么不是抛出的错误? 为什么服务器崩溃。

一种解决scheme…

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

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

再一次…为什么? 为什么如果brother obj是null,Mongoose甚至试图删除文件? 为什么服务器崩溃?

//我使用Express 4.13.4和Mongoose 4.4.12

感谢您的帮助,并赦免任何新手无知。

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

find0文件不是错误,find的行为被执行了,但是发现了0个事情。

Mongoose有一个帮助函数findOneAndRemove ,你应该使用它,less写代码,less些头疼:

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

err是在事件发生的情况下抛出的,无法连接到数据库,无效的身份validation等。但是对于查询,只要查询正确,它就会抛出任何错误。 在你查询返回0行的情况下,它会简单地调用你的callbacknull ,所以你可能希望在使用brother之前进行检查。

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

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