7

最近、pg モジュール (https://github.com/brianc/node-postgres) も使用する、express.js ベースのアプリケーションの作業を開始しました。

また、ノードとエクスプレス アプローチのエラー処理、ミドルウェアを適切に設計することの利点などについて読むのにかなりの時間を費やしました。

たとえば、次のルーターメソッドがあります。

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 メソッドをインターセプトすることを含みます。1 つは、クエリ メソッドがエラーをコールバックに渡すのではなく、単純にスローすることです。別の例では、pgClient.query への呼び出しは、ルーター メソッドの next を pgClient に送信します。次に、インターセプトされたクエリ メソッドは、次に渡されるメソッドを処理する方法を認識します。

私の知る限り、エラーをスローすることは、実際には 500 ハンドラーに到達するための適切な方法ではありません。一方、pgClient へのオプションとして next を渡すと、上記のレイヤーに関する多くの知識がこのような低レベルに与えられます。これは、私の知識と経験に基づいて、結合につながる可能性があり、あまり良くありません。

何を指示してるんですか?

4

1 に答える 1

11

connect-domainミドルウェアを使用できます。Doman APIconnectexpress基づいて動作します。

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