Что такое ошибка Мангуста, приведенная к объекту ObjectId failed для значения XXX по пути "id"?
при отправке запроса к /customers/41224d776a326fb40f000001
и документ с _id
41224d776a326fb40f000001
не существует, doc
и null
и я возвращаю a 404
:
Controller.prototype.show = function(id, res) {
this.model.findById(id, function(err, doc) {
if (err) {
throw err;
}
if (!doc) {
res.send(404);
}
return res.send(doc);
});
};
, когда _id
не соответствует тому, что Мангуст ожидает, как "формат" (я предполагаю), например GET /customers/foo
странная ошибка:
CastError: Cast to ObjectId failed для значения " foo "по пути"_id".
так что же это за ошибка?
12 ответов:
Мангуст это
findById
метод бросаетid
параметр типа модели_id
поле, чтобы он мог правильно запросить соответствующий документ. Это объект, но"foo"
не является допустимым идентификатором ObjectId поэтому приведение завершается неудачей.это не происходит с
41224d776a326fb40f000001
потому что эта строка является допустимым значением ObjectId.один из способов решить эту проблему-добавить чек до вашего
findById
позвоните, чтобы узнать, еслиid
является допустимым ObjectId или не так:if (id.match(/^[0-9a-fA-F]{24}$/)) { // Yes, it's a valid ObjectId, proceed with `findById` call. }
используйте существующие функции для проверки ObjectID.
var mongoose = require('mongoose'); mongoose.Types.ObjectId.isValid('your id here');
вы разбираете эту строку как
ObjectId
?вот в моем приложении, что я делаю:
ObjectId.fromString( myObjectIdString );
вы также можете использовать ObjectId.isValid выглядит следующим образом:
if (!ObjectId.isValid(userId)) return Error({ status: 422 })
Это старый вопрос, но вы также можете использовать пакет экспресс-валидатора для проверки параметров запроса
экспресс-валидатор версии 4 (последняя):
validator = require('express-validator/check'); app.get('/show/:id', [ validator.param('id').isMongoId().trim() ], function(req, res) { // validation result var errors = validator.validationResult(req); // check if there are errors if ( !errors.isEmpty() ) { return res.send('404'); } // else model.findById(req.params.id, function(err, doc) { return res.send(doc); }); });
экспресс-валидатор версии 3:
var expressValidator = require('express-validator'); app.use(expressValidator(middlewareOptions)); app.get('/show/:id', function(req, res, next) { req.checkParams('id').isMongoId(); // validation result req.getValidationResult().then(function(result) { // check if there are errors if ( !result.isEmpty() ) { return res.send('404'); } // else model.findById(req.params.id, function(err, doc) { return res.send(doc); }); }); });
if(mongoose.Types.ObjectId.isValid(userId.id)) { User.findById(userId.id,function (err, doc) { if(err) { reject(err); } else if(doc) { resolve({success:true,data:doc}); } else { reject({success:false,data:"no data exist for this id"}) } }); } else { reject({success:"false",data:"Please provide correct id"}); }
лучше всего проверить действительность
Я пошел с адаптацией решения @gustavohenke, реализуя cast ObjectId в try-catch обернутый вокруг исходного кода чтобы использовать сбой приведения ObjectId в качестве метода проверки.
Controller.prototype.show = function(id, res) { try { var _id = mongoose.Types.ObjectId.fromString(id); // the original code stays the same, with _id instead of id: this.model.findById(_id, function(err, doc) { if (err) { throw err; } if (!doc) { res.send(404); } return res.send(doc); }); } catch (err) { res.json(404, err); } };
или вы можете сделать это
var ObjectId = require('mongoose').Types.ObjectId; var objId = new ObjectId( (param.length < 12) ? "123456789012" : param );
Как уже упоминалось здесь метод поиска Мангуста с $ или условием не работает должным образом
всегда использовать
mongoose.Types.ObjectId('your id')
для условий в вашем запросе он будет проверять поле id перед запуском запроса, в результате чего ваше приложение не будет аварийно завершать работу.
я столкнулся с этой проблемой, потому что я объявлял маршрутизатор как
router.put('/:id', async (req, res) => { // code .... }
и обновлял данные с url, т. е.
http://localhost:3000/id=5af584ebb62aae2fa8e406a2
после долгого времени я исправляю себя, удаляя
id=
какправильный путь был:
http://localhost:3000/5af584ebb62aae2fa8e406a2
теперь я могу использовать
findById()
какlet myModel = await Model.findById(req.params.id);