为什么我无法捕获来自node-postgres抛出的错误?

4

我遇到了一个问题,即无法从 Node-Postgres NPM 包中捕获错误。

这个问题表面上似乎很简单,但是我已经尝试了我能想到的一切方法。

我的代码如下:

import { Pool } from 'pg' // Import postgres connection pool
const pgPool = new Pool()

async function queryDatabase() {
  try {

    // Force TypeError by passing undefined
    let queryResult = await pgPool.query( undefined )

    if ( queryResult.rows.length > 0 ) {
      return queryResult.rows[0]
    }

    return false

  } catch( err ) {

    // Never Reached
    return new Error( 'Test error' )

  }
}
queryDatabase()

错误如下:

TypeError: 客户端传递了一个空的或未定义的查询
at Client.query (~/.../node_modules/pg/lib/client.js:479:11)

这个错误本身已经很明显了。为了试图处理由于误传 undefined 而产生的错误,我在这里强制出错。我知道我可以简单地检查以确保输入永远不会是 null 或 undefined,但那不是我的主要关注点。

我的担心是,如果我无法捕获从这个包抛出的错误,那么我将遇到多少其他未预料到的情况,我根本无法捕获和处理所抛出的错误。

我尝试了许多不同的方法 - 上面展示的 Async/Await Try/Catch 方法,我尝试了 pgPool.query().then().catch(),两者的组合。我甚至尝试对 Pool 实例本身运行 catch。无论我做什么,都无法处理异常,除非使用 Node 的 process.on('unhandledRejection', ...),这当然是个坏主意。

我已经头疼了几个小时了。有没有办法捕获和处理这样的错误,使其不会每次崩溃我的服务器?提前感谢!


https://stackoverflow.com/questions/58831423/how-can-i-improve-error-handling-on-a-pool - Teemu
我很感激您的快速回复,但那并不起作用。pg包没有通过它们的错误处理程序路由这个特定的错误。他们只是抛出它。 - AustinPhillipTaylor
如果传递 undefined 导致上述代码无法捕获的异常,那就是一个 bug。请确保您拥有最新版本的 pg,然后在 GitHub 上报告此问题。 - Bergi
1个回答

4
我能够重现这个问题,看起来这是pg库中的一个实际 bug。
根据源代码,如果你在一个池实例上调用.query,这个实例将尝试连接并获取客户端。在连接回调中,实际查询被分发到客户端模块,如果查询为 nil,则会抛出上述类型错误 该错误是同步抛出的(即错误不会传递给回调参数,例如callback(new TypeError("...")),并且由于在池的连接回调中没有try/catch围绕client.query调用,因此错误将不会被您的try/catch捕获。
一种可能的解决方法是在 client.query 调用中加入 try catch:
 client.once('error', onError)
      this.log('dispatching query')
      try {
        client.query(text, values, (err, res) => {
          this.log('query dispatched')
          client.removeListener('error', onError)
          if (clientReleased) {
            return
          }
          clientReleased = true
          client.release(err)
          if (err) {
            return cb(err)
          } else {
            return cb(undefined, res)
          }
        })
      }catch(err) {
        return cb(err)
      }

所以现在,您可能应该在 Github 上创建一个问题并等待错误修复,或者分叉存储库并使用上述解决方法,恐怕如此。

3
非常感谢您的回复。很遗憾,这是一个包的问题。我想我的困惑源于不知道抛出的错误不会沿着调用堆栈向上冒泡。这似乎相当低效。 - AustinPhillipTaylor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接