Handling errors in nodejs and express

Many people surely know all this by now. Still, here are some things I’ve recently learned about notifying clients (browsers, API clients) about errors.

Delivering errors from route handlers to clients

This is remarkably easy, once you figure it out. Just use the http-errors package. (Beware, not the http-error package; it does something different. Call next() with an object made with createError(status, message).

const createError = require('http-errors')
 ...
router.post('/', function(req, res, next) {
  next(createError(400, 'you cannot POST to this endpoint'))
});

You’ll deliver the status and error code to the error handler.

Client-sensitive error handling

express’s default error handler delivers a web page, typically a 404-type page, to the client. That may not be what you want if you have non-browser clients. This adaptation of the error handler in the express template app makes it deliver error messages in the form of a page, or JSON, or plain text.

app.use(function (err, req, res, next) {
  res.locals.message = err.message
  res.locals.error = 
      req.app.get('env') === 'development' ? err : {}

  if (req.accepts('html')) {
    res
     .status(err.status || 500)
     .render('error')
  } else if (req.accepts('json')) {
    res
      .status(err.status)
      .json({ 
          status: err.status, 
          name: err.name,
          message: err.message })
  } else {
    res
    .status(err.status)
    .send(`${err.status}: ${err.message}\r\n`)
  }
})

What’s going on? It’s about the if / else if / else sequence. if (req.accepts('html')) checks the Accept header from the client to see whether the client accepts html. We similarly check for JSON.

This error handler delivers an appropriate error document to each type of client, depending on what it can handle.

Leave a Comment