2016-08-18 4 views
1

私はこのような非常に基本的な移行コードを持っています。これは、テーブルを削除し、テーブルを作成し、いくつかのデータをシードします。NodeJS/Expressでの適切なエラー処理

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

お気づきのとおり、コードの3倍.catch((err) => console.log(err))チェーンがあります。

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

私はこのような何かをやって考えている:別の問題をabrings

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

この方法を私はすべてのエラーをキャッチし、私のコードを乾かすが、私は、ノードがフッキング例外をサポートしているかはわからないことができます。

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

答えて

1

まず、this.knex.schema.createTableは約束を返しますか?以下のようなので、あなたは、少しきれいな方法でこのロジックを記述することができた場合は(あなたはいつもそれが約束を返すように変換することができない場合):配列から任意の約束は拒否した場合、あなたならば

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()を使用できます(何かつまり、http://bluebirdjs.com/docs/api/reflect.html持ってdoesntのノードでネイティブの約束をサポート)あなたが使用することを考慮することができ

第二に、代わりにconsole.logの(console.errorまたは何でも)ブンヤンのようなものhttps://github.com/trentm/node-bunyan

第3に、一般的に、あなたはいつも私がコードにバグでは、あなたが知っておく必要があるだろう、私の視点からキャッチ法に

を追加し忘れた場合どう

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

のように、uncaughtExceptionに対するあなたのアプリを守るために必要その。 あなたのような、コールバックでエラーを処理することを忘れようにそれは同じである:だけでなく、単にあなたがエラーを処理していない、それを置くために、

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

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

また、あなたが恩恵を受けることができるもう1つ、あなたの質問でExpressを挙げました。いくつかの特別なエラー処理ロジックがない場合は、(このハンドラにreturn next(err)経由でエラーを渡すことができます任意の経路からこれにより

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

、:あなたはなど、すべてのあなたのルートの後に定義する必要がグローバルエラーハンドラを登録することができます必要な、特定のエンドポイントに固有の)、ログエラーなどのエラーを処理してから500を何らかのメッセージで返すことができる場所を確保します。 https://expressjs.com/en/guide/error-handling.html

+0

驚くべき答えに感謝します。 createTableが約束を返さない場合、私は約束を返すためにそれを変換できますか?また、Bluebirdとは何ですか?また、配列マップの完成をどのように理解していますか?今はちょうど別の 'save(...)、then(...)'約束です。私は約束をいつかすぐに読む必要があると思う。これについてあなたが提案できるものはありますか? – Aris

+0

あなたの推測は正しいです。まず、約束事に精通していなければなりません。本当に助けてくれるもの:https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html – Srle

+0

私は読んでいますそれ。それは私の質問のほとんどに答えます。しかし、私はどのように私はこれを約束することができるか分からない: 'this.knex.schema.createTable'。また、将来、約束を返さないものを約束する必要がある場合は、どうすればいいですか?メソッドをオーバーライドして 'Promise.something()'を返しますか? – Aris

関連する問題