क्या आब्जेक्शन के लिए Mongoose एरर कास्ट "पथ" पर मूल्य XXX के लिए विफल रही?


122

जब एक अनुरोध /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मोंगोज़ को "प्रारूप" के रूप में क्या उम्मीद नहीं है , तो मैं GET /customers/fooएक अजीब त्रुटि के साथ उदाहरण के लिए (मुझे लगता है) वापस आ गया है:

CastError: CastI to ObjectId "" fid "पथ में मूल्य" फू "के लिए विफल रहा।

तो यह त्रुटि क्या है?

जवाबों:


182

Mongoose की findByIdविधि idपैरामीटर को मॉडल के _idक्षेत्र के प्रकार में डालती है ताकि मिलान डॉक के लिए ठीक से क्वेरी कर सके। यह एक ObjectId है, लेकिन "foo"एक मान्य ObjectId नहीं है, इसलिए कलाकार विफल रहता है।

ऐसा 41224d776a326fb40f000001इसलिए नहीं होता क्योंकि यह स्ट्रिंग एक मान्य ऑब्जेक्ट है।

इसे हल करने का एक तरीका यह है कि आपके findByIdकॉल से पहले एक चेक जोड़ा idजाए ताकि यह पता चले कि वैध ऑब्जेक्टआईड है या नहीं।

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

4
@Gremo आपको केवल _idअपने Mongoose स्कीमा में उपयोग के लिए एक प्रकार चुनना है । में "bla"मामला आप का एक प्रकार का प्रयोग करेंगे Stringबजाय डिफ़ॉल्ट ObjectIdऔर आप इस चेक को जोड़ने के लिए के रूप में कुछ भी एक स्ट्रिंग के लिए डाली जा सकती है, जरूरत नहीं होगी।
जॉनीएचके

2
मैं समझता हूं, लेकिन मैं इस जांच से बचना चाहता हूं। मैं इसे ObjectIdदिए गए तरीके से ( GETअनुरोध से) एक नया तरीका कैसे बना सकता हूं findById?
ग्रेमो

@Gremo आप नहीं कर सकते। आप केवल 24 हेक्स कैरेक्टर स्ट्रिंग्स से ऑब्जेक्ट्स का निर्माण कर सकते हैं।
जॉनीएचके

1
आप केवल उस (अद्वितीय) आईडी के साथ दस्तावेज़ के लिए क्वेरी करने के लिए खोज ({_ id: yourId}, ...) का उपयोग कर सकते हैं। वह, और अपने स्कीमा में _id जोड़ने के लिए जॉनीएचके का उत्तर (आपके वांछित 'स्ट्रिंग' प्रकार के साथ) आपकी समस्या का पूर्ण समाधान है।
स्टीव होलास्च

1
इन दिनों, 12 चरित्र तार भी एक ObjectId के लिए डाले जा सकते हैं। ObjectId("000000000000") --> 303030303030303030303030
डैन रॉस

50

ऑब्जेक्ट की जाँच के लिए मौजूदा कार्यों का उपयोग करें।

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

15
उस विधि का उपयोग करने में सावधानी बरतें क्योंकि इसमें किसी भी 12-बाइट स्ट्रिंग को वैध मानने का जिज्ञासु व्यवहार है। तो यह आपके 'your id here'उदाहरण के लिए भी सही है । github.com/mongodb/js-bson/issues/106
जॉनीएचके

console.log ( "यहाँ"); आइए i = new mongoose.Types.ObjectId (userId.id); कंसोल.लॉग ("अब यहाँ"); // यह सांत्वना भी नहीं
छप रही है

11

क्या आप उस स्ट्रिंग को पारस कर रहे हैं ObjectId?

यहाँ मेरे आवेदन में, मैं क्या कर रहा हूँ:

ObjectId.fromString( myObjectIdString );

हाँ, आपको चाहिए, क्योंकि आप एक ObjectId प्रकार की क्वेरी कर रहे हैं, इसलिए कलाकारों की आवश्यकता है।
gustavohenke

1
कोशिश करो mongoose.Types.ObjectId

1
काम करता है, लेकिन "फू" पास करते समय मुझे "अमान्य ऑब्जेक्टआईड" मिलता है। तो एक स्ट्रिंग से एक ObjectId बनाने का क्या मतलब है, अगर यह विफल हो सकता है?
ग्रेमो

MongoDB डॉक्स के अनुसार, ObjectIds केवल 24 हेक्साडेसिमल बाइट्स होना चाहिए।
gustavohenke

1
fromStringएक कार्य नहीं है
वासिफ

8

मेरे पास एक ही मुद्दा है मैं
_id: स्ट्रिंग .in स्कीमा को जोड़ता हूं फिर यह काम शुरू करता है


एक साल बाद कनेक्ट-मोंगो के साथ उपयोग करने पर इसने मुझे बचाया
Ren44

15 घंटे तक सीधे काम करने के बाद धन्यवाद आपको एक छोटे से बिंदु पर अटक गया।
ब्लैक माम्बा

8

मुझे अपने मार्गों को उन अन्य मार्गों से ऊपर ले जाना पड़ा जो मार्ग मापदंडों को पकड़ रहे हैं:

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

वह यह था। काश मुझे एक घंटे पहले आपका जवाब मिल जाता। चीयर्स!
सोड्बिलग गानसुख

इसने मेरे लिए काम किया। मैं इस त्रुटि के पीछे के कारण के लिए उत्सुक हूं। क्या आप बता सकते हैं कि नियमित मार्गों से नीचे जाने वाले मार्ग को कैसे आगे बढ़ने में त्रुटि हुई?
विश्वकूट

इसने मुझे भी काम दिया। ऐसा लगता है कि The / test / create satisfies this / test /: id with id = create। और स्ट्रिंग को to_id पर नहीं डाला जा सकता है।
kaila88

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

वैधता की जांच करना सबसे अच्छा है


3

मेरे मामले में, मुझे _id: Objectअपनी स्कीमा में शामिल होना पड़ा , और फिर सब कुछ ठीक चला।


2

आप निम्न की तरह ObjectId.isValid का भी उपयोग कर सकते हैं:

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

1
ReferenceError: ObjectId को परिभाषित नहीं किया गया है
torbenrudgaard

2
//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
}

अन्य उत्तर हैं जो ओपी के प्रश्न प्रदान करते हैं, और वे कई साल पहले पोस्ट किए गए थे। उत्तर पोस्ट करते समय, कृपया सुनिश्चित करें कि आप या तो एक नया समाधान जोड़ते हैं, या काफी बेहतर व्याख्या करते हैं, खासकर पुराने प्रश्नों का उत्तर देते समय। कोड-केवल उत्तरों को निम्न गुणवत्ता माना जाता है: यह सुनिश्चित करना सुनिश्चित करें कि आपका कोड क्या करता है और यह समस्या को हल कैसे करता है।
help-info.de

2

मुझे हाल ही में कुछ इसी तरह का सामना करना पड़ा था और यह एक Mongoose ObjectId त्रुटि है यह पता लगाने के लिए त्रुटि को पकड़कर इसे हल किया।

app.get("/:userId", (req, res, next) => {
    try {
        // query and other code here
    } catch (err) {
        if (err.kind === "ObjectId") {
            return res.status(404).json({
                errors: [
                    {
                        msg: "User not found",
                        status: "404",
                    },
                ],
            });
        }
        next(err);
    }
});


1

मैं @gustavohenke समाधान के एक अनुकूलन के साथ गया था, ऑब्जेक्ट कोड को एक सत्यापन विधि के रूप में विफल करने के लिए मूल कोड के चारों ओर लिपटे एक कोशिश-कैच में ऑब्जेक्ट ऑब्जेक्ट को लागू करना ।

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

1
यह उपयोग करने के लिए अच्छा होता, लेकिन fromString () अब मौजूद नहीं है: github.com/Automattic/mongoose/issues/1890
ब्रेंट वाशबर्न

1

यह एक पुराना प्रश्न है, लेकिन आप अनुरोध पार्म्स की जांच के लिए एक्सप्रेस-वैलिडेटर पैकेज का भी उपयोग कर सकते हैं

एक्सप्रेस-सत्यापनकर्ता संस्करण 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);
        });

    });

});

1

हमेशा mongoose.Types.ObjectId('your id')अपनी क्वेरी में शर्तों के लिए उपयोग करें यह आपकी क्वेरी को चलाने से पहले आईडी फ़ील्ड को मान्य करेगा परिणामस्वरूप आपका ऐप क्रैश नहीं होगा।



0

जिस तरह से मैं इस समस्या को ठीक करता हूं वह आईडी को एक स्ट्रिंग में बदल रहा है

मुझे यह पसंद है कि बैकटिक के साथ फैंसी: `${id}`

यह ओवरहेड के साथ समस्या को ठीक करना चाहिए


0

ObjectId निम्नलिखित चीजों से बना है।

  1. यूनिक्स युग के बाद से सेकंड का प्रतिनिधित्व करने वाला 4-बाइट मान
  2. 5-बाइट रैंडम वैल्यू (मशीन आईडी 3 बाइट्स और प्रोसेसर आईडी 2 बाइट्स)
  3. एक 3-बाइट काउंटर, एक यादृच्छिक मूल्य के साथ शुरू।

यदि ऑब्जेक्ट मान्य है, तो सही तरीका ऑब्जेक्टआईड क्लास से स्थिर विधि का उपयोग करके मान्य है।

mongoose.Types.ObjectId.isValid (sample_object_id)


0

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

0

वस्तु त्रुटि का पता लगाना और उसे ठीक करना

मैं इस समस्या में लड़खड़ा गया जब किसी वस्तु का उपयोग करके हटाने की कोशिश की गई और वही त्रुटि मिली। रिटर्न स्ट्रिंग को देखने के बाद, मैंने पाया कि रिटर्न स्ट्रिंग के अंदर कुछ अतिरिक्त स्थान थे जो मेरे लिए त्रुटि का कारण बने। इसलिए, मैंने गलत आईडी का पता लगाने के लिए यहां दिए गए कुछ उत्तरों को लागू किया और फिर स्ट्रिंग से अतिरिक्त स्थान हटा दिए। यहाँ वह कोड है जो मेरे लिए समस्या को हल करने के लिए काम करता है।

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

यह मेरे लिए काम करता है और मुझे लगता है कि यदि अन्य आइटम रिटर्न स्ट्रिंग में दिखाई देने लगते हैं तो उन्हें इसी तरह से हटाया जा सकता है।

आशा है कि ये आपकी मदद करेगा।


0

मैंने मार्गों के क्रम को बदलते हुए इस समस्या को ठीक किया।


यह कोई उत्तर नहीं लगता। सबसे अच्छा, यह एक टिप्पणी है।
MS

इसने मेरे लिए काम किया, मेरे पास ब्लॉगों के लिए 2 मार्ग थे: '/ ब्लॉग्स / क्रिएट' और 'ब्लॉग्स /: आईडी'। और बाद वाले मार्गों के क्रम में सबसे पहले आए। इसलिए जब मैं '/ ब्लॉग्स / क्रिएट' में गया तो
मानसून ने

0

मुझे इससे समस्या हो रही थी और mongoose.ObjectId(id)बिना कुछ किए तय किया जा रहा थाTypes

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.