0
votes

I'm trying to get my head around why the if(!document) is not executed when a document is not found, but instead the app jumps straight to the catch block and returns the 500 status instead?

To clarify, there's no problem with the id sent via req.body.id, if I send a valid ID that matches a doc in the db the success block is executed. The problem is when I send an ID that doesn't match a doc the if (!document) {} block is not executed, but instead the catch block is executed.

My intention is this (if the code example is not clear enough):

if the document is not found return: return res.status(401).json({ message: 'Unauthorized.' }

If the document is found: return res.status(200).json({ message: 'Authorized.' });

If there's a db / server error: return res.status(500).json({ message: 'Internal server error.' })

Small code example below:

const login = (req, res) => {
    userSchema
        .findById(req.body.id)
        .then((document) => {
            if (!document) {
                return res.status(401).json({ message: 'Unauthorized.' }).end();
            }
            return res.status(200).json({ message: 'Authorized.' });
        })
        .catch((err => return res.status(500).json({ message: 'Internal server error.' });
};
1
console.log(req.body.id) right after const login = (req, res) => { will tell you everything you need to know.codemonkey
Side note; from a security standpoint, this feels unsafe. Your authentication process appears to be based solely on the user passing in a valid user record id. A user authentication token should be based on a session, which eventually will expire, not a user record id that will not change.Taplar
It's just a simplified example...octavemirbeau
req.body.id has nothing to do with this, I can retrieve movies without any problem as long as the id sent is correct. The question is why when I put an incorrect id the if(!document) is not executed, but instead the catch block.octavemirbeau

1 Answers

1
votes

In order to successfully execute this part:

userSchema
        .findById(req.body.id)
          ...

req.body.id has to be a value castable to an ObjectId. Otherwise you will see this error CastError: Cast to ObjectId failed for value..., which, of course, will trigger the catch block.

So, for example, if req.body.id is 604156ee6db28527531bd612, which is perfectly castable to ObjectId, your query will actually execute and, if no results are found, will trigger your if block.

If, however, req.body.id is, say, sh21343dfs or an empty string, then findById will throw the CastError mentioned above and send you straing into the catch block.

So just use the catch as your cue to send back something like a User Not Found error, because there are very few other things can trigger that catch block in findById

Or you could expicitly check for the validity of the string like so:

const ObjectID = require('mongodb').ObjectID;
...
...
if(ObjectID.isValid(req.body.id))
    return res.status(401).json({ message: 'Unauthorized.' }).end();