3
// @route   GET api/profile/handle/:handle
// @desc    Get profile by handle
// @access  Public

router.get('/handle/:handle', (req, res) => {
    const errors = {};

    Profile.findOne({ handle: req.params.handle })
        .populate('user', ['name', 'avatar'])
        .then(profile => {
            //console.log('profile1 ' + profile);
            if (!profile) {
                errors.noprofile = 'There is no profile for this user for handle route (from then block)';
                res.status(404).json(errors);
            }
            res.json(profile);
        })
        .catch(err => res.status(404).json({ profile: 'There is no profile for this user for handle route (from error block)' }));

});

// @route   GET api/profile/user/:user_id
// @desc    Get profile by user ID
// @access  Public

router.get('/user/:user_id', (req, res) => {
    const errors = {};

    Profile.findOne({ user: req.params.user_id })
        .populate('user', ['name', 'avatar'])
        .then(profile => {
            // console.log('profile not found by userid');
            //console.log('profile2 ' + profile);
            if (!profile) {
                errors.noprofile = 'There is no profile for this user for user_id route (from then block)';
                res.status(404).json(errors);
            }
            res.json(profile);
        })
        .catch(err => res.status(404).json({ profile: 'There is no profile for this user for user_id route (from error block)',
err: err }));
});

I have these two routes as above. First one is to search an user from dB using the handle(username) and the second one is to search using the user_id created by dB itself. When I am requesting to the 1st route using a wrong handle , the then() block gets executed and i got this response:

{
    "noprofile": "There is no profile for this user for handle route (from then block)"
}

But in the second route (searching by user_id), when i am putting an wrong user_id, the catch block gets executed and i got this response:

{
    "profile": "There is no profile for this user for user_id route (from error block)",
    "err": {
        "message": "Cast to ObjectId failed for value \"5cb0ec06d1d6f93c20874427rhdh\" at path \"user\" for model \"profile\"",
        "name": "CastError",
        "stringValue": "\"5cb0ec06d1d6f93c20874427rhdh\"",
        "kind": "ObjectId",
        "value": "5cb0ec06d1d6f93c20874427rhdh",
        "path": "user"
    }
}

The logic is same for both the routes ,but they are responding differently.What is the reason behind this???

if u want to have a look on Profile schema, here it is:

const ProfileSchema = new Schema({
    user: {
        type: Schema.Types.ObjectId,
        ref: 'users'
    },
    handle: {
        type: String,
        required: true,
        max: 40
    },
    company: {
        type: String
    },
   ....
....
.....
});

I got a warning too while requesting with a wrong handle as below:

(node:16996) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:470:11)
    at ServerResponse.header (H:\MERN Stack Course\devConnector\node_modules\express\lib\response.js:767:10)
    at ServerResponse.send (H:\MERN Stack Course\devConnector\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (H:\MERN Stack Course\devConnector\node_modules\express\lib\response.js:267:15)
    at Profile.findOne.populate.then.catch.err (H:\MERN Stack Course\devConnector\routes\api\profile.js:75:39)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:16996) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:16996) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Dev_spidey
  • 51
  • 6

2 Answers2

0

check the error message

"message": "Cast to ObjectId failed for value \"5cb0ec06d1d6f93c20874427rhdh\" at path \"user\" for model \"profile\""

user field is of mongodb type ObjectId and you're providing String while handle is of type String

In case of handle query there was no error, only there was no entry in your db.

You can fix it like mongoose.Types.ObjectId(req.params.user_id). More here

Also, there's problem with your code. (Execution doesn't stop where you think it stops and you get unhandled promise rejection)

.then(profile => {
  //console.log('profile1 ' + profile);
  if (!profile) { // <--- if true
    errors.noprofile = 'There is no profile for this user for handle route (from then block)';
    res.status(404).json(errors); // <-- executes
  }
  res.json(profile); // <--- always executes within then callback
})

If this check if (!profile) evaluates to true then res.status(404).json(errors) is executed. And then next res.json(profile) is executed.

In your code res.json(profile) is always executed when there's no error. You could rectify by either using return to stop execution or if..else like:

return res.status(404).json(errors);

// or
if (!profile) {
  errors.noprofile = 'There is no profile for this user for handle route (from then block)';
  res.status(404).json(errors);
} else {
  res.json(profile);
}
1565986223
  • 6,420
  • 2
  • 20
  • 33
-1

I think in your second route you're trying to query with an invalid ObjectID.

Pls check: What's Mongoose error Cast to ObjectId failed for value XXX at path "_id"?

bmz1
  • 188
  • 2
  • 8
  • yes, that's what my question is, i am knowingly request with a wrong user_id. The issue is when I request with a wrong handle, it executes the then() block, but in case of the second route ,when I request with a wrong user_id , it executes the catch() block. – Dev_spidey Apr 18 '19 at 14:19
  • You misunderstood me. I know it's intentionally wrong. But the type of it is invalid. That's why you get CastError. Please check this: const valid = mongoose.Types.ObjectId.isValid(req.params.user_id); – bmz1 Apr 18 '19 at 14:25
  • But I am not interested in what type of error it's coming,I want to know why it is not throwing any error in the 1st route, both have the same logic. And i had tested this with wrong number and string types of user_id , it's saying the same cast error. – Dev_spidey Apr 18 '19 at 14:33