xunux
xunux

Reputation: 1769

Why does catch() block in mongoose query not exit the function when returning next(err)?

I have this basic function being called by my express router.

export const createThing = async(req,res,next) => {
    const {body} = req;
    const thing = await Thing.create(body).catch(err=>next(err));
    
    console.log('should ignore me on error')

    res.send(tran);
};

I am purposefully sending a body with incomplete fields as required by the Thing model, and it is firing an error in the catch block, which in turn triggers all the error middleware i have in place, however, i would expect it to exit the function since im returning next(err) at the catch, but it still continues with the rest of the function.

I tried removing the const thing = so that instead of returning the results of my query/catch to a variable, i simply execute it as await Thing.create(...).catch(...) and while that fixes other issues in my error reporting im not mentioning it here, it is STILL console.logging 'should ignore me on error'.

So my question is why isnt the function exiting when it catches the error? Should i be doing that manually somehow? im not just calling next(err) im returning it in the catch block, and i'd expect it to not continue with the function, which then has other errors because im setting headers with res.send() for example, and i would want it to exit the function on error.

Upvotes: 0

Views: 331

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370779

.catch will turn a Promise that rejects into a Promise that resolves to the value returned from the .catch. Your current code, when .create rejects, results in this expression:

Thing.create(body).catch(err=>next(err));

becoming a Promise that resolves to what's returned by next(err).

Since the Promise resolves (and doesn't reject), the const thing = await // ... will not throw; execution flow will continue as normal.

You could have the .catch return the error in the case of an error, and check that outside the await:

const thing = await Thing.create(body).catch(err => { next(err); return err; });
if (thing && thing instanceof Error) {
  return;
}

Or just use .then:

export const createThing = async (req, res, next) => {
    const { body } = req;
    Thing.create(body)
        .then(() => {
            console.log('should ignore me on error')
            res.send(tran);
        })
        .catch(err => next(err));
};

Upvotes: 1

Related Questions