在基于express.js的应用程序中集中错误处理

时间:2012-12-29 10:43:47

标签: node.js error-handling express

我刚刚开始研究基于express.js的应用程序,它也使用了pg模块(https://github.com/brianc/node-postgres)

我还花了很多时间,阅读有关节点和表达方法错误处理,正确设计中间件的好处等等。然而,如果没有解决方案,一个反复出现的问题仍然在嗡嗡作响。

说,我有以下路由器方法:

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
  });
});

如果我读得正确,这应该是正确的方法。然而,我敢打赌,你也可以一点也不认识到,重复一遍又一遍地重写,即使在我们有多个嵌套回调的情况下,即使是在相同的路由器方法中也是如此。

我一直在问自己,集中处理这种情况的最佳方法是什么。我的所有想法都涉及拦截pgClient.query方法。在一个方面,查询方法将简单地抛出错误而不是将其传递给回调。在另一个中,对pgClient.query的调用将在pgClient旁边发送路由器方法。然后截获的查询方法将知道如何处理传递给它的下一个。

据我所知,抛出错误并不是真正适合500名处理程序的方法。另一方面,作为pgClient的一个选项,下一步传递,给出了如此低级别的关于上面层的很多知识,这基于我的知识和经验,可以导致耦合,并且也不是很好。

你有什么建议?

1 个答案:

答案 0 :(得分:11)

您可以使用connect-domain中间件。它适用于connectexpress,并基于Doman API。

您需要在堆栈中添加connect-domain中间件作为第一个中间件。就这样。现在,您可以在异步代码中的任何地方抛出错误,它们将使用域中间件处理并传递给表达错误处理程序。

简单示例:

// 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');
    });
});