7

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

我还花费了大量时间,阅读有关节点和 express 方法错误处理、正确设计中间件的好处等内容。然而,一个反复出现的问题仍然困扰着我,但没有解决方案。

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

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 的调用会将路由器方法的 next 发送到 pgClient。然后被拦截的查询方法将知道如何处理下一个被传递给它的方法。

据我所知,抛出错误并不是将其传递给 500 个处理程序的正确方法。另一方面,passin next 作为 pgClient 的一个选项,在如此低的层次上提供了很多关于上面层的知识,根据我的知识和经验,这会导致耦合,也不是很好。

你有什么建议?

4

1 回答 1

11

您可以使用连接域中间件。它使用connectexpress基于Doman API。

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

简单的例子:

// 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');
    });
});
于 2012-12-29T14:47:49.093 回答