Over a million developers have joined DZone.

Catch Errors in Express.js Application

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

This is a small follow up for my previous post, using the same technique, not for authorization, but rather for error handling.

Let’s go back to the problem. I want to handle all errors in my application. Instead of res.send() or res.json(), I want to have a middleware that handles everything by itself. It can be flexible, so I can put any kind of logic there, like logging, etc.

It’s very easy to archive with patch the middleware method.

Just like in the previous case, app.use() won’t work here. First, it would apply to every request. Second, error handling middleware has to be placed last and app.use() won’t guarantee that.

Follow the Style

To get the benefits of common error handling/logging code, you have to follow a particular style. It’s very simple though.

Your last endpoint (middleware) function has to always receive the next() callback parameter. All logs have to pass as the first argument to that function. You should not send errors directly as res.send(500, 'Error').

app.get('/api/users/:id', function (req, res, next) {
  db.users.find({id: req.params.id}, function (err, user) {
      if (err) {
          return next({message: 'failed to query db', status: 500});
      }

      if (!user) {
          return next({message: 'user not found', status: 404});
      }

      res.json(user);
  });
});

Please note that it receives the first argument and the function is only called when we call next() with the first parameter.

Error Handler Middleware

Let’s define the function. Since HTTP API’s are JSON based, it would just return the JSON response and status.

function logErrors(err, req, res, next) {
  req.unhandledError = err;

  var message = err.message;
  var error = err.error || err;
  var status = err.status || 500;

  res.json({message: message, error: error}, status);
};

Apply the Patch

Again, right after all routes are already defined, let’s call applyErrorLogging().

// ...

require('./source/api')(app);
require('./source/router')(app);

applyAuthentication(app, ['/api']);
applyErrorLogging(app);                 // apply error handling here

// ...

And the applyErrorLogging() function,

var middleware = require('../middleware');

function applyErrorLogging(app) {
  for (var verb in app.routes) {
      var routes = app.routes[verb];
      routes.forEach(patchRoute);
  }

  function patchRoute (route) {
      route.callbacks.push(middleware.errors.logErrors);
  }
}

module.exports = applyErrorLogging;




Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:

Published at DZone with permission of Alexander Beletsky, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}