Madeline Ries
Madeline Ries

Reputation: 629

throw error versus normal return in express

I know how to write simple API using node.js (express). But now I'm confused and couldn't differentiate this two block of code

if(err){ return res.status(500).json(err) }
return res.json(result)

versus

if(err) { throw new Error(err) }
return res.json(result)

What is the standard for a API response? I simply return 2 property, like

if(err){ return res.json({ status: false, msg: 'user password is incorrect }) }
return ({ status: true, msg: result.token })

What's wrong with my approach and why we should use throw?

Upvotes: 1

Views: 1773

Answers (1)

Paul
Paul

Reputation: 36349

You don't generally want to throw an error in Express at all, because unless it's caught it will crash the process without giving your user warning, and it's not easy to catch the error and maintain the request context to do so otherwise.

Instead the choice in an Express handler should be between directly returning an error response (as in your example) and calling next(err). In my apps I always do the latter, because it lets me set up error handling middlware to always and consistently handle the various problem cases.

Example below:

app.get('/something', (req, res, next) => {
  // whatever database call or the like
  Something.find({ name: 'something'}, (err, thing) => {
     // some DB error, we don't know what. 
     if (err) return next(err);
     // No error, but thing wasn't found
     // In this case, I've defined a NotFoundError that extends Error and has a property called statusCode set to 404. 
     if (!thing) return next(new NotFoundError('Thing was not found'));
     return res.json(thing);
  });
});

Then some middleware for handling errors like so:

app.use((err, req, res, next) => {
  // log the error; normally I'd use debug.js or similar, but for simplicity just console in this example
  console.error(err);

  // Check to see if we have already defined the status code
  if (err.statusCode){
    // In production, you'd want to make sure that err.message is 'safe' for users to see, or else use a different value there
    return res.status(err.statusCode).json({ message: err.message }); 
  }
  return res.status(500).json({ message: 'An error has occurred, please contact the system administrator if it continues.' });
});

Note that nearly everything in Express is done through middleware.

Upvotes: 2

Related Questions