正确的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