【问题标题】:What is the proper way to handle Knex pg database errors处理 Knex pg 数据库错误的正确方法是什么
【发布时间】:2021-07-06 20:07:33
【问题描述】:

我正在使用带有 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
}

有没有办法处理这样的错误?

【问题讨论】:

    标签: javascript postgresql error-handling knex.js


    【解决方案1】:

    捕获 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 团队成员)

    【讨论】:

    • 非常感谢您的快速回答,但实际上我不是在谈论如何捕获错误,我只是想知道是否可以检查错误的类型。这个想法是我想集中错误处理。那么有没有办法做到这一点'error instanceof DatabaseError'
    • 很好,但是没有办法使用这个钩子向客户端发送响应。当我发现错误时,我想检查其类型,然后向客户端发送自定义错误消息。
    • 添加了另一个编辑:简而言之,您想要的不存在,因为 PG 无法识别自己的错误,并且 Knex(旨在与许多 DB 一起使用)不知道错误...因为它们因数据库而异。
    • P.S.您可以查看错误详细信息(例如code === 'ECONNREFUSED')并做出回应,实际上这可能会解决您想要解决的任何问题...除非您专门尝试创建一个自定义消息“一个(模糊的,即不是“连接被拒绝”)错误专门发生在 PG 中,而不是在 Knex 中。但老实说,您的用户是否真的关心他们的网站为什么无法运行,详细程度如此之高?
    • 最后一个想法:如果您的目标是“确定我们的数据库何时运行异常和破坏东西”,您还可以使用 PG 特定的错误处理程序在您的Express 服务器,'导致所有后续 Knex 错误处理程序检查该 var,并发送特殊的“DB Broke”消息,直到该标志被清除。但同样,我不确定大多数网站所需的工作是否合理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-02
    • 2017-09-20
    • 2021-12-16
    相关资源
    最近更新 更多