মোজুজ ত্রুটিটি কাস্ট টু অবজেক্টআইডে "_id" পথে 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: কাস্ট টু অবজেক্টআইড "_id" পথে "foo" মানের জন্য ব্যর্থ হয়েছে।

তাহলে এই ত্রুটিটি কী?

উত্তর:


182

মঙ্গুসের findByIdপদ্ধতিটি idমডেলের _idক্ষেত্রের ধরণের পরামিতিটিকে কাস্ট করে যাতে এটি ম্যাচের ডকটির জন্য সঠিকভাবে জিজ্ঞাসা করতে পারে। এটি একটি অবজেক্টআইড তবে "foo"বৈধ অবজেক্টআইড নয় তাই কাস্ট ব্যর্থ হয়।

এটি এর সাথে ঘটে না 41224d776a326fb40f000001কারণ স্ট্রিংটি একটি বৈধ অবজেক্টআইডি।

এটি সমাধানের একটি উপায় হ'ল আপনার findByIdকলের আগে একটি চেক যুক্ত করা idএটি বৈধ অবজেক্টআইড কিনা তা পছন্দ করে দেখুন:

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

4
@ গ্রেমো আপনার মঙ্গুজ স্কিমাতে আপনি কেবল এক প্রকারের জন্য বেছে নিতে পারেন _id। সেক্ষেত্রে "bla"আপনি Stringডিফল্ট পরিবর্তে এক ধরণের ব্যবহার করবেন ObjectIdএবং কোনও স্ট্রিংতে কিছু ফেলে দেওয়া যেতে পারে তাই আপনার এই চেকটি যুক্ত করার দরকার পড়বে না।
জনিএইচকে

2
আমি বুঝতে পারি, তবে আমি এই চেকটি এড়াতে চাই। পদ্ধতিটিতে পাস করার জন্য আমি ObjectIdকোনও প্রদত্ত স্ট্রিং ( GETঅনুরোধ থেকে ) থেকে কীভাবে একটি নতুন তৈরি করতে পারি findById?
গ্রিমো

@ গ্রেমো আপনি পারবেন না আপনি কেবল 24 হেক্স অক্ষরের স্ট্রিং থেকে অবজেক্টআইডস তৈরি করতে পারেন।
জনিএইচকে

1
আপনি সেই (অনন্য) আইডি সহ নথির জন্য ক্যোয়ারী করার জন্য কেবল ({_ id: yourId}, ...) ব্যবহার করতে পারেন। এটি, এবং আপনার স্কিমে _id যুক্ত করার জন্য জনিএইচকে উত্তর (আপনার পছন্দসই 'স্ট্রিং' টাইপ সহ) আপনার সমস্যার পুরো সমাধান।
স্টিভ হোল্যাশ

1
এই দিনগুলিতে, 12 টি অক্ষরের স্ট্রিংও একটি অবজেক্টআইডে কাস্ট করা যেতে পারে। 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 ( "এখানে"); আসুন আমি = নতুন মঙ্গুজ.প্রযুক্তি.অবজেক্টআইডি (ইউজারআইডি.আইডি); কনসোল.লগ ("এখন এখানে"); // এই কনসোলটি এমনকি মুদ্রণ করছে না
যোগেশ অগ্রওয়াল

11

আপনি কি সেই স্ট্রিংকে পার্স করছেন ObjectId?

আমার আবেদনটিতে এখানে আমি যা করছি তা হ'ল:

ObjectId.fromString( myObjectIdString );

হ্যাঁ, আপনার করা উচিত, কারণ আপনি একটি অবজেক্টআইডি টাইপ অনুসন্ধান করছেন, তাই কাস্ট প্রয়োজন is
গুস্তাভোহেঙ্কে

1
ব্যবহার করে দেখুন mongoose.Types.ObjectId
গুস্তাভোহেঙ্কে

1
কাজ করে, তবে "foo" পাস করার সময় আমি "অবৈধ অবজেক্টআইডি" পাই। সুতরাং একটি স্ট্রিং থেকে একটি অবজেক্টআইডি তৈরি করার বিন্দুটি কী, যদি এটি ব্যর্থ হতে পারে?
গ্রিমো

মঙ্গোডিবি ডক্স অনুসারে, অবজেক্টআইডগুলি অবশ্যই 24 হেক্সাডেসিমেল বাইট হতে হবে।
গুস্তাভোহেঙ্কে

1
fromStringকোনও ফাংশন নয়
ওয়াসিফ

8

আমার একই সমস্যাটি আমি যুক্ত করছি
_ আইডি: স্ট্রিং 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);

ঐটা এটা ছিল. আমি আশা করি আমি আপনার উত্তরটি এক ঘন্টা আগে পেয়েছি। চিয়ার্স!
সোডব্লেগ গানসুখ

এটি আমার পক্ষে কাজ করেছে। আমি এই ত্রুটির পিছনে কারণ সম্পর্কে আগ্রহী। আপনি কি দয়া করে ব্যাখ্যা করতে পারেন যে নিয়মিত রুটের নীচে রুটটি সরিয়ে নিয়ে যাওয়ার ফলে ত্রুটিটি কীভাবে চলে গেল?
বিশ্বক

এটি আমার পাশাপাশি কাজ করেছে। দেখে মনে হচ্ছে / পরীক্ষা / তৈরি এই / পরীক্ষার /: আইডি = তৈরির সাথে সন্তুষ্ট করে। এবং স্ট্রিংকে_আইডিতে কাস্ট করা যাবে না।
কৈলা 88

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

আপনি নীচের মত অবজেক্টআইডি.আইভিড ব্যবহার করতে পারেন:

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

1
রেফারেন্সএরর:
অবজেক্টআইড

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


1

আমি বৈধতা পদ্ধতি হিসাবে অবজেক্টআইডি কাস্টিংয়ের ব্যর্থতা অবলম্বন করতে মূল কোডের চারপাশে মোড়ানো একটি চেষ্টা করে কাস্ট অবজেক্টআইডকে বাস্তবায়িত করে @ গুস্তাভোহেনকে সমাধানের সাথে অভিযোজন করেছি ।

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
এটি ব্যবহারে ভাল লাগত তবে স্ট্রিং () থেকে আর বিদ্যমান নেই: 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')আপনার ক্যোয়ারির শর্তগুলির জন্য ব্যবহার করুন এটি আপনার ক্যোয়ারি চালানোর আগে আইডি ফিল্ডটিকে বৈধতা দেবে ফলস্বরূপ আপনার অ্যাপ্লিকেশন ক্রাশ হবে না।


1

আমি সম্প্রতি কিছু অনুরূপ সমস্যার মুখোমুখি হয়েছি এবং এটি একটি মঙ্গুজ অবজেক্টআইড ত্রুটি কিনা তা অনুসন্ধান করার জন্য ত্রুটিটি ধরা দিয়ে সমাধান করেছি।

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


0

এই সমস্যাটি আমি যেভাবে সংশোধন করব তা হ'ল আইডিটিকে স্ট্রিংয়ে রূপান্তরিত করে

আমি ব্যাকটিক সঙ্গে অভিনব পছন্দ: `${id}`

এটি কোনও ওভারহেড ছাড়াই সমস্যাটি ঠিক করবে


0

অবজেক্টআইডি নিম্নলিখিত জিনিসগুলির সমন্বয়ে গঠিত।

  1. ইউনিক্স পর্বের সময় থেকে সেকেন্ডে প্রতিনিধিত্বকারী একটি 4-বাইট মান
  2. একটি 5 বাইট র্যান্ডম মান (মেশিন আইডি 3 বাইট এবং প্রসেসর আইডি 2 বাইট)
  3. একটি 3 বাইট কাউন্টার, এলোমেলো মান দিয়ে শুরু।

অবজেক্টআইডিটি বৈধ হলে বৈধতা দেওয়ার সঠিক উপায়টি অবজেক্টআইড শ্রেণি থেকেই স্ট্যাটিক পদ্ধতি ব্যবহার করে।

mongoose.Types.ObjectId.isValid (sample_object_id)


0

অবজেক্টআইডে কাস্টিং স্ট্রিং

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

মুগুজ

ব্যবহার করে কোনও আইটেম মোছার চেষ্টা করার সময় আমি এই সমস্যাটিতে হোঁচট খেয়েছি এবং একই ত্রুটি পেয়েছি ject রিটার্নের স্ট্রিংটি দেখার পরে আমি দেখতে পেলাম যে রিটার্নের স্ট্রিংয়ের অভ্যন্তরে কিছু অতিরিক্ত জায়গা রয়েছে যা আমার জন্য ত্রুটি তৈরি করেছিল। সুতরাং, আমি ভ্রান্ত আইডি সনাক্ত করার জন্য স্ট্রিং থেকে অতিরিক্ত স্পেসগুলি সরাতে এখানে প্রদত্ত কয়েকটি জবাব প্রয়োগ করেছি remove শেষ পর্যন্ত সমস্যাটি সমাধান করার জন্য কোডটি আমার পক্ষে কাজ করেছে।

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

রুটের ক্রম পরিবর্তন করে আমি এই সমস্যার সমাধান করেছি।


এটি কোনও উত্তর বলে মনে হয় না। সর্বোপরি, এটি একটি মন্তব্য।
এমএস

এটি আমার পক্ষে কাজ করেছে, আমার ব্লগের জন্য দুটি রুট ছিল: '/ ব্লগস / তৈরি' এবং 'ব্লগ /: আইডি'। এবং পরবর্তীগুলি রুটের ক্রমে প্রথমে আসে। সুতরাং আমি যখন '/ ব্লগস /
ক্রিয়েটিং
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.