0

I'm trying to add a new route to fetch a user by id but my error handling is not working correctly. Here is the code for that route.

const express = require('express');

require('./db/mongoose');
const User = require('./models/user');
const Task = require('./models/task');

const app = express();
const port = process.env.PORT || 3000;

app.use(express.json());

//  ***removed code for brevity
// Route for fetching user by id

app.get('/users/:id', (req, res) => {
    //console.log(req.params.id);
    const _id = req.params.id;

    User.findById(_id)
        .then(user => {
            //console.log(user)
            if (!user) {
                return res.status(404).send();
            }
            res.send(user);
        })
        .catch(e => {
            res.status(500).send();
        });
});

So if I test the route on Postman and I enter the correct user id from the database I get that user sent back, which is the the correct response. But if I enter an incorrect user id I get the 500 error code response instead of the 404 error code. The if (!user) statement is getting skipped and I can't figure out why. Any thoughts as to what I am missing?

Leo Policastro
  • 1,062
  • 1
  • 8
  • 16
  • this means you have an error in `User.findById` your catching its error and sending 500 status .. could you post the code and how it's exported? also you could `console.log(e)` in `catch(e)` block and you will see what is the error thrown – fedesc Mar 17 '19 at 18:35
  • So this is the entire User file I am requiring – Leo Policastro Mar 17 '19 at 18:43
  • ```const User = new mongoose.model('User', { name: { type: String, required: true, trim: true }, email: { type: String, require: true, trim: true, lowercase: true, validate(value) { if (!validator.isEmail(value)) { throw new Error('Email is invalid'); } } }, password: { type: String, required: true, trim: true, minlength: 7, validate(value) { let pwd = value.toLowerCase().includes('password'); if (pwd) { console.log("Your password can't contain the word password."); } } // if include password },``` – Leo Policastro Mar 17 '19 at 18:48
  • Not sure why it looks like that sorry. But I am exporting it by calling module.exports = User – Leo Policastro Mar 17 '19 at 18:49
  • If you would log `e` instead of just ignoring it, you would probably know the error. – Jonas Wilms Mar 17 '19 at 18:49
  • and when I console .log(e) i get this error message: 'Cast to ObjectId failed for value "5c8e62681df87697a8dbc2f" at path "_id" for model "User"', along with a lot of other information I can post if you'd like. – Leo Policastro Mar 17 '19 at 18:52
  • check this answer refering to you received error which is a mongoose err https://stackoverflow.com/a/14942113/1283672 – fedesc Mar 17 '19 at 18:53

1 Answers1

0

Running this thru my own personal mongoose/express-using project, I get the following error:

 UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed for value "12345" at path "_id" for model "User"

That basically means Mongoose is expecting its own specific object type, an "ObjectId". This is a bit of a pain, since normally if you're using .findOne({_id:something), you can just use a string. If we do:

User.findById(mongoose.Types.ObjectId(_id))

it should work. Note that if you use an invalid id (like I obviously did here, it'll still error out. For that reason, I'd use the standard NodeJS format for callbacky stuff:

.then((err,result)=>{
   //other stuff
});

In general, the .catch() block should only happen if obviously Mongoose and your router can't handle it.

EDIT: Also, for others info, Mongoose.model.findById is a built-in convenience method, and should basically do exactly what it says on the tin.

Newms
  • 124
  • 1
  • 6