Derek
Derek

Reputation: 19

How to catch 4xx and 5xx errors in express?

Lets say that a user is creating an account, but the inputs aren't valid, so I send the errors to the frontend and return a 409 status code. But when the error is in the server side, I don't want to return a 409 status code, but a 5xx status code. How can I achieve this?

exports.signup = (req, res) => {
  try {
    //pseudocode
    db.createUser(req.user);
    res.status(201).send("user created!");
  } catch (err) {
    const errors = { username: "", password: "" };
    //pseudocode
    forEach((error) => { 
        if(validation.error.username) {
          errors.username = validation.error.username
        } else {
          errors.password = validation.error.password
        })
    res.status(409).json(errors);
  }
};

Upvotes: 2

Views: 1172

Answers (2)

raina77ow
raina77ow

Reputation: 106385

Instead of handling errors inside each route, consider using set of error handling middleware, like described in this article. For example:

app.use(function handleNotFoundError(error, req, res, next) {
  if (error instanceof NotFoundError) {
    return res.status(HttpStatus.NOT_FOUND).send({
      httpStatus: HttpStatus.NOT_FOUND,
      message: error.message,
      error: {}
    });
  }
  next(error);
});

app.use(function handleValidationError(error, req, res, next) {
  if (error instanceof ValidationError) {
    return res
      .status(HttpStatus.BAD_REQUEST)
      .json({
        httpStatus: HttpStatus.BAD_REQUEST,
        message: error.message,
        validationErrors: error.validationErrors
      });
  }
  next(error);
});

// ... etc.

The benefit of this approach is creating an error-handling layer, essentially wrapping your routing code and the corresponding services. The latter then should only worry about throwing correct errors (both by types and related data).

You can take this approach even further by creating so-called Error Router: map of the functions, using NotFoundError, ValidationError etc. as keys and corresponding handlers as values. Once again, the benefit is that you won't have to worry about sending 'proper' codes and data inside your controllers and/or services; its responsibility ends up on throwing correct errors.

Upvotes: 1

Reynau
Reynau

Reputation: 304

You could validate the inputs on a first step and return a 4xx in case they are invalid. If they are valid, in a second step, you could store the data and return a 5xx status code if an error happens server-side.

Upvotes: 0

Related Questions