Подтвердить что ты не робот

Какая ошибка Mongoose Cast to ObjectId не удалась для значения XXX по пути "_id"?

При отправке запроса на /customers/41224d776a326fb40f000001 и документа с _id 41224d776a326fb40f000001 не существует, doc есть null, и я возвращаю 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 не соответствует тому, что ожидает Mongoose как "формат" (я полагаю), например, с помощью GET /customers/foo возвращается странная ошибка:

CastError: Cast to ObjectId не удалось присвоить значение "foo" в пути "_id".

Итак, что это за ошибка?

4b9b3361

Ответ 1

Метод Mongoose findById передает параметр id в тип поля модели _id, чтобы он мог правильно запросить соответствующий документ. Это ObjectId, но "foo" не является допустимым ObjectId, поэтому сбой выполняется.

Это не происходит с 41224d776a326fb40f000001, потому что эта строка является допустимым ObjectId.

Один из способов решения этой проблемы - добавить проверку перед вызовом findById, чтобы увидеть, является ли id допустимым ObjectId или нет:

if (id.match(/^[0-9a-fA-F]{24}$/)) {
  // Yes, it a valid ObjectId, proceed with `findById` call.
}

Ответ 2

Используйте существующие функции для проверки ObjectID.

var mongoose = require('mongoose');
mongoose.Types.ObjectId.isValid('your id here');

Ответ 3

Вы разбираете эту строку как ObjectId?

Здесь, в моем приложении, я делаю:

ObjectId.fromString( myObjectIdString );

Ответ 4

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

Ответ 5

Вы также можете использовать ObjectId.isValid, как показано ниже:

if (!ObjectId.isValid(userId)) return Error({ status: 422 })

Ответ 6

Мне пришлось переместить мои маршруты поверх других маршрутов, которые отслеживают параметры маршрута:

// require express and express router

const express = require("express");
const router = express.Router();

// move this '/post/like' route on top

router.put("/post/like", requireSignin, like);

// keep the route with route parameter '/:postId' below regular routes

router.get("/post/:postId", singlePost);

Ответ 7

Это старый вопрос, но вы также можете использовать пакет express-validator для проверки параметров запроса

Экспресс-валидатор версии 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);
        });

    });

});

Ответ 8

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

лучше всего проверить правильность

Ответ 9

//Use following to check if the id is a valid ObjectId?

var valid = mongoose.Types.ObjectId.isValid(req.params.id);
if(valid)
{
  //process your code here
} else {
  //the id is not a valid ObjectId
}

Ответ 10

Я пошел с адаптацией решения @gustavohenke, реализуя cast ObjectId в try-catch , обернутом вокруг исходного кода, чтобы использовать отказ метода CastId как метод проверки.

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

Ответ 12

Всегда используйте mongoose.Types.ObjectId('your id') для условий в вашем запросе. Он проверит поле идентификатора перед выполнением запроса, в результате ваше приложение не будет аварийно завершено.

Ответ 13

Привести строку в ObjectId

import mongoose from "mongoose"; // ES6 or above
const mongoose = require('mongoose'); // ES5 or below

let userid = _id
console.log(mongoose.Types.ObjectId(userid)) //5c516fae4e6a1c1cfce18d77

Ответ 14

Способ решения этой проблемы - преобразование идентификатора в строку.

Мне нравится это с галочкой: '${id}'

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

Ответ 15

ObjectId состоит из следующих вещей.

  1. 4-байтовое значение, представляющее секунды с начала эпохи Unix
  2. 5-байтовое случайное значение (идентификатор машины 3 байта и идентификатор процессора 2 байта)
  3. 3-байтовый счетчик, начиная со случайного значения.

Правильный способ проверки правильности objectId - использование статического метода из самого класса ObjectId.

mongoose.Types.ObjectId.isValid(sample_object_id)

Ответ 16

Обнаружение и исправление ошибки ObjectID

Я столкнулся с этой проблемой при попытке удалить элемент с помощью mongoose и получил ту же ошибку. Просматривая возвращаемую строку, я обнаружил, что внутри возвращенной строки было несколько лишних пробелов, что вызвало для меня ошибку. Итак, я применил несколько ответов, представленных здесь, чтобы обнаружить ошибочный идентификатор, а затем удалить лишние пробелы из строки. Вот код, который помог мне окончательно решить проблему.

const mongoose = require("mongoose");
mongoose.set('useFindAndModify', false);  //was set due to DeprecationWarning: Mongoose: 'findOneAndUpdate()' and 'findOneAndDelete()' without the 'useFindAndModify'



app.post("/delete", function(req, res){
  let checkedItem = req.body.deleteItem;
  if (!mongoose.Types.ObjectId.isValid(checkedItem)) {
    checkedItem = checkedItem.replace(/\s/g, '');
  }

  Item.findByIdAndRemove(checkedItem, function(err) {
    if (!err) {
      console.log("Successfully Deleted " + checkedItem);
        res.redirect("/");
      }
    });
});

Это сработало для меня, и я предполагаю, что если другие элементы начинают появляться в возвращаемой строке, они могут быть удалены аналогичным образом.

Надеюсь, это поможет.

Ответ 17

Если кто-то сталкивается с этим, то, что я решил, менялось с одной цитаты в требовании '.

Вместо:

const something = require('./models/something');

использовать:

const something = require('./models/something');

Знайте, это звучит смешно, но на самом деле это работает.

Ответ 18

В моем случае мне пришлось добавить _id: Object в мою схему, и тогда все работало нормально.