我有一个非常基本的迁移代码,如下所示。它删除表,创建表,并用一些数据为它播种。
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
块中的逻辑。
我正在考虑做这样的事情:
.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
});
这样我可以捕获所有错误并干掉我的代码,但我不确定Node是否支持挂钩异常。
在我的案例中你会做什么,我应该采取什么样的方法?我想确保所有错误都正确发送到Bugsnag。
答案 0 :(得分: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
将返回被拒绝的承诺,如果数组中的任何承诺拒绝,如果您发现这不符合您的需求,您可以使用bluebird中的.reflect()
(节点中本机承诺支持的东西不具备, http://bluebirdjs.com/docs/api/reflect.html)
其次,你可以考虑使用像bunyan,https://github.com/trentm/node-bunyan
这样的东西,而不是console.log(console.error或其他)。第三,一般来说,您总是需要针对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
,简单地说就是你没有处理错误。根据经验,不要只测试晴天情景,就像一切顺利。针对代码中的不同场景进行测试,包括将会发生某些事情的下雨天场景,确保您以正确的方式处理它。
还有一件事你可以从中受益,你在问题中提到Express
。您可以在所有路径之后注册需要定义的全局错误处理程序,例如:
app.use((err, req, res, next) => {
...
})
通过这种方式,您可以从任何路径通过return next(err)
将错误传递给此处理程序(如果不需要某些特殊错误处理逻辑,特定于特定端点),确保一个地方可以处理错误例如记录错误并返回500
一些消息或其他内容。 https://expressjs.com/en/guide/error-handling.html