捕获 Knex/DB 错误:
您可以使用async/await 语法:
async function() {
try {
await knex(/* knex query here*/)
} catch(error) {
if(error instanceof DatabaseError) {
// handle pg error by checking error.code or something else
// then send an custom error message to the client
}Sorry
// handle another error here which is not caused by the postgres server
}
如果由于某种原因您不想使用该(较新的)语法,您也可以链接 .catch ...
knex(/* knex query here*/)
.then(doWhatever)
.catch(error => {
if(error instanceof DatabaseError) { // ...
});
您也可以使用 Knex 的查询错误 (https://knexjs.org/#Interfaces-query-error) ...但我个人从未见过内置的 Promise 处理程序可以正常工作。
(编辑)区分 PG 错误和 Knex 错误:
如果您想区分 Knex 和 PG 特有的错误,您可以像这样直接将错误处理程序连接到您的 PG 连接(绕过 Knex):
function afterCreate(connection, callback) {
connection.on("error", connectionError);
callback(null, connection);
}
db.client.pool.config.afterCreate = afterCreate;
如果这样做,您将不需要error instanceof DatabaseError,因为connection.on 捕获的所有错误都是 PG 错误。
您可能还会发现此问题线程(我从中获取该代码)很有用:https://github.com/knex/knex/issues/522,因为它讨论了 Knex 中的错误处理,特别是底层数据库错误的处理。
(编辑)但是我如何区分错误当我发现它们时?
不幸的是,我认为 PG 错误没有独特的原型(即类)或其他显着特征。您可以通过查看一个示例(来自我链接的那个线程)来了解这一点:
{"code":"ECONNREFUSED","errno":"ECONNREFUSED","syscall":"connect","address":"127.0.0.1","port":5432}
如您所见,除非您开始检查特定功能,例如 code === 'ECONNREFUSED'(错误中没有 isPg: true 标志),否则无法查看并知道“它来自 PostgreSQL”。
为什么 Knex 不能智能地为我们识别数据库错误?从同一个问题线程:
几乎不可能像 redis 那样为 knex 创建事件,因为有大量不同的数据库驱动程序实际上并不支持监听连接错误
-elhigu(Knex 团队成员)