1

このような非常に基本的な移行コードがあります。テーブルを削除し、テーブルを作成して、いくつかのデータをシードします。

this.knex.schema.dropTable(this.tableName)
.catch((err) => console.log(err))
.then(() => {
    this.knex.schema.createTable(this.tableName, function(table) {
        table.increments("id").primary();
        table.string("name");
        table.integer("parent_id").unsigned().default(0);
    })
    .catch((err) => console.log(err))
    .then(() => {
        this.categories.forEach((category) => {
            Category.create(category)
            .catch((err) => console.log(err))
            .then((category) => console.log(category.get("name") + " seeded."))
        });
    });
});

お気づきかもしれませんが.catch((err) => console.log(err))、コードには 3x チェーンがあります。

現在、アプリケーションに Bugsnag を統合しており、すべてのバグを修正できるように Bugsnag のすべての例外/エラーを適切にログに記録したいと考えています。ただし、今できることは、コンソールにログインすることだけです。さらに悪いことに、私は自分自身を繰り返し、各catchブロックでロジックを複製します。

私はこのようなことを考えています:

.catch((err) => ErrorHandler.add(err))

class ErrorHandler {

    add(err) {
        // Notify Bugsnag
        // Log it to console
    }

}

それは別の問題を引き起こします。メソッドの追加を忘れたらどうなりますかcatch...それでも機能しません。

このようなことも考えました:

// Change exception behaviour so whenever they are called, they raise an  `onException` event
app.listen("onException", (err) => {
    // Notify Bugsnag
    // Log error to console
});

このようにして、すべてのエラーをキャッチしてコードを DRY できますが、Node が例外のフックをサポートしているかどうかはわかりません。

私の場合、あなたは何をし、どのようなアプローチをとるべきですか? すべてのエラーが正しく Bugsnag に送信されるようにしたいと考えています。

4

1 に答える 1

1

まずthis.knex.schema.createTable、約束を返しますか?(そうでない場合は、常に promise を返すように変換できます) その場合、次のように、このロジックをもう少しクリーンな方法で記述できます。

this.knex.schema.dropTable(this.tableName)
.then((...) => {
  ...
  return this.knex.schema.createTable(...)
})
.then((...) => {
 ... // do whatever you are doing with table object
  return Promise.all( map and do whatever you are doing with categories)
})
.then(() => {
  // log that everything went well with seeding
})
.catch((err) => {
  // single catch block to handle errors from this promise chain
})

Promise.all配列からのプロミスが拒否された場合、拒否されたプロミスを返します。これがニーズに合わないことがわかった場合は.reflect()、bluebird から使用できます (ノードのネイティブ プロミス サポートにないもの、http://bluebirdjs.com/docs/api/reflect .html )

次に、console.log (console.error など) の代わりに、bunyan のようなものを使用することを検討できます。 https://github.com/trentm/node-bunyan

uncaughtException第三に、一般に、次のように常にアプリを防御する必要があります

process.on('uncaughtException', (err) => {
  ...
}) 

catch メソッドの追加を忘れた場合

私の観点からすると、それはコードのバグであり、そのことに注意する必要があります。次のように、コールバックでエラーを処理するのを忘れているのと同じです。

doSomething((err, data) => {
  // do something with data without checking against err
})

したがって、同じ質問をすることができますWhat if I forget to check against err。簡単に言えば、エラーを処理していません。経験則として、すべてがうまくいったように、晴れた日のシナリオだけをテストしないでください。何かがスローされる雨の日のシナリオなど、コード内のさまざまなシナリオに対してテストし、適切な方法で処理していることを確認します。

また、質問で述べたように、もう1つメリットがありますExpress。次のようなすべてのルートの後に定義する必要があるグローバルエラーハンドラーを登録できます。

app.use((err, req, res, next) => {
  ...
})

これにより、任意のルートreturn next(err)からこのハンドラーにエラーを渡すことができます (特定のエンドポイントに固有の特別なエラー処理ロジックが必要ない場合) 500。メッセージでも何でも。https://expressjs.com/en/guide/error-handling.html

于 2016-08-18T13:04:07.140 に答える