正确的error handling与NodeJS / Express

我有一个非常基本的迁移代码,看起来像这样。 它删除表格,创build表格,并用一些数据对其进行种子处理。

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

您可能会注意到,代码上有3x .catch((err) => console.log(err))链。

现在我已经将Bugsnag集成到了我的应用程序中,并且要确保在Bugsnag上正确logging了所有exception/错误,以便我可以修复所有的错误。 不过,现在我所能做的就是将它们login到控制台中。 更糟的是,我重复自己,重复每个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 }); 

这样我可以捕获所有的错误,干我的代码,但我不知道如果节点支持挂钩exception。

你会怎么做,我应该采取什么样的方法? 我想确保所有错误都正确地发送到Bugsnag。

首先,这个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将返回被拒绝的承诺,如果有任何数组拒绝的承诺,如果你发现这不符合你的需要,你可以使用bluebird的.reflect() (本地承诺支持的节点没有http:// bluebirdjs。 com / docs / api / reflect.html )

其次,而不是console.log(console.error或其他),你可以考虑使用像bunyan, https://github.com/trentm/node-bunyan

第三,一般来说,你总是需要防御你的应用程序,像uncaughtException

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

如果我忘记添加捕捉方法会怎么样?

从我的angular度来看,这将是代码中的错误,你需要意识到这一点。 像你忘记处理callback错误一样,例如:

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

所以同样的问题可能会被问到, What if I forget to check against err ,那么简单地说你没有处理错误。 根据经验,不要只testing晴天的情况,就像一切顺利。 在你的代码中testing不同的场景,包括有些东西会丢失的雨天场景,确保你以正确的方式处理它。

另外还有一件事可以从中受益,你在问题中提到了Express 。 您可以注册全局error handling程序,您需要在所有路由之后定义,如:

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

有了这个,你可以通过任何路由将错误通过return next(err)传递给这个处理程序(如果某些特定的error handling逻辑不需要,特定于特定的端点),确保从一个地方处理错误,如日志错误,并返回500与一些消息或任何。 https://expressjs.com/en/guide/error-handling.html