我试着研究这个问题的原因;这很可能是我对Mongoose工作方式的误解。我正在尝试用REST风格创建一个CRUD后端。 GET,PUT,POST似乎都有效。但是,我对DELETE动词的问题有点不知所措。
我和Postman一起向mongo输入了一些假数据,一切顺利。所以我复制了我的一个记录的_id字段并尝试删除。当我发送DELETE请求时,成功消息通过,记录确实已从mongo中删除。但是,在删除其他记录后,我决定尝试删除包含已删除文档的_id的记录。
我向'api / brothers / 57280602953cff031f21ad9c'发送了DELETE请求
原来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...
根据我的理解,没有抛出错误,因为如果它被抛出,我的if
语句就会执行并将错误返回给用户。如果我在url中输入了一个伪造的id,那么我会收到一个错误,但是如果我粘贴了一个我已经删除的记录的_id,则不会抛出错误,并且执行会移动到else
块,并且继续删除不存在的文档。甚至.remove()
似乎都没有发现错误......服务器崩溃了。
所以......我的问题是为什么?是否与Mongo施放_id
有关?为什么不抛出错误?为什么服务器崩溃。
如果我修改if
语句不仅要捕获错误,还要检查是否存在从brother
函数返回的findById()
,则会返回错误避免了用户和灾难:
if (err || !brother) {
// THIS WORKS
res.json(brother);
} else { ...
再次......为什么?为什么如果brother
obj为null,Mongoose甚至会尝试删除文档?为什么服务器会崩溃?
//我正在使用Express 4.13.4和Mongoose 4.4.12
感谢您的帮助,并原谅任何新手的无知。
答案 0 :(得分:4)
你得到的是一个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) {
});
});
答案 1 :(得分:1)
err
。但对于查询,只要查询正确,它就会抛出任何错误。在您的查询返回0
行的情况下,它只会使用null
调用您的回调,因此您可能需要在使用brother
之前进行检查。
答案 2 :(得分:0)
在使用删除之前,你必须检查兄弟是否存在,如果找不到项目,moongoose将不会返回错误。
if(!brother){
return res.status(400).send('Item Not Found')
}