Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Centralizing error handling in an express.js-based app

I just recently started working on an express.js based application, which also uses the pg module (https://github.com/brianc/node-postgres)

I also spent a significant amount of time, reading about node and express approach error handling, the benefits of properly designing middleware, etc. Yet, a recurring problem is still buzzing me without a solution.

Say, I have the following router method:

app.get("/:someThing/:someId", function(req, res, next) {
  pgClient.query("some SQL query", function(err, data) {
    if (err) { return next(err); } // some 500 handler will take it
    if (data.rows.length == 0) {
      next(); // send it over to a 404 handler
    }

    //finally, here we get the chance to do something with the data.
    //and send it over via res.json or something else
  });
});

If I've read correctly, this should be the proper way to do it. Yet, I bet you can also admt that it is too much of boilerplate to rewrite over and over ... and over again, even in the very same router method, in case we have multiple nested callbacks.

I've been asking myself what the best way to handle such a situation centrally would be. All of my ideas involve intercepting the pgClient.query method. In one, the query method will simply throw the error instead of passing it to the callback. In another, the call to the pgClient.query will send the router method's next to pgClient. Then the intercepted query method will know how to deal with the next being passed to it.

From what I know, throwing errors around is not really the appropriate way to get it to the 500 handlers. On another hand, passin next as an option to pgClient, gives such a low level a lot of knowledge about the the layers above, which based on my knowledge and experience, can lead to coupling, and is not very good either.

What do you suggest?

like image 599
user1219569 Avatar asked Dec 29 '12 10:12

user1219569


People also ask

How can you deal with error handling in ExpressJS explain with an example?

For example: app. get('/', (req, res) => { throw new Error('BROKEN') // Express will catch this on its own. }) If getUserById throws an error or rejects, next will be called with either the thrown error or the rejected value.

What is centralized error handling?

Centralized way involves some sort of central database or storage of errors (usually a module or a header file) where are all the error messages stored. In code you pass an error code to some function and it does all the work for you. A big plus of this approach is that you have everything in one place.


1 Answers

You can use connect-domain middleware. It works with connect and express and based on Doman API.

You need to add connect-domain middleware as first middleware in stack. Thats all. Now you can throw errors everywhere in your async code and they will be handled with domain middleware and passed to express error handler.

Simple example:

// Some async function that can throw error
var asyncFunction = function(callback) {
    process.nextTick(function() {
        if (Math.random() > 0.5) {
            throw new Error('Some error');
        }
        callback();
    });
};

var express = require('express');
var connectDomain = require('connect-domain');

var app = express();
app.use(connectDomain());
// We need to add router middleware before custom error handler
app.use(app.router);

// Common error handler (all errors will be passed here)
app.use(function(err, req, res, next){
    console.error(err.stack);
    res.send(500, 'Something broke!');
});

app.listen(3131);

// Simple route
app.get('/', function(req, res, next) {
    asyncFunction(function() {
        res.send(200, 'OK');
    });
});
like image 167
Vadim Baryshev Avatar answered Oct 20 '22 14:10

Vadim Baryshev