Что такое ошибка Мангуста, приведенная к объекту ObjectId failed для значения XXX по пути "id"?


при отправке запроса к /customers/41224d776a326fb40f000001 и документ с _id41224d776a326fb40f000001 не существует, 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 66

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);

У меня та же проблема, которую я добавляю
_id: String. in схема, то он начинает работать

способ устранения этой проблемы заключается в преобразовании идентификатора в строку

Мне нравится это фантазии с backtick: `${id}`

это должно решить проблему без накладных расходов