处理 Knex pg 数据库错误的正确方法是什么

What is the proper way to handle Knex pg database errors

我正在使用带有 knex javascript 库的 postgres 来构建我的 sql 查询。我想处理来自 postgres 服务器的所有抛出的错误,所以我想这样做的方法是检查抛出的错误的类型。

try {
   // 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
    }

    // handle another error here which is not caused by the postgres server
}

有什么办法可以处理这样的错误吗?

捕获 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 中的错误处理,特别是底层数据库错误的处理。

(EDIT) 但是我如何区分错误 当我发现错误时?

不幸的是,我不认为 PG 错误没有独特的原型(即 class)或其他显着特征。您可以通过查看示例一(来自我链接的那个线程)来了解这一点:

{"code":"ECONNREFUSED","errno":"ECONNREFUSED","syscall":"connect","address":"127.0.0.1","port":5432}

如您所见,除非您开始检查 code === 'ECONNREFUSED' 等特定功能(没有 isPg: true 标志错误)。

为什么 Knex 不直接为我们智能识别数据库错误?来自同一问题线程:

It is pretty much impossible to create events like redis have for knex because of multitude of different db drivers which doesn't actually support listening for connection errors

-elhigu(Knex 团队成员)