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') }