【问题标题】:node-postgres gives “Error: timeout expired”node-postgres 给出“错误:超时已过期”
【发布时间】:2021-10-26 00:51:18
【问题描述】:

我有这个超级简单的 node-postgres 示例,但我无法运行:

const { Client } = require('pg')

const postgresOptions = {
  connectionString: 'postgres://REDACTED:REDACTED@hattie.db.elephantsql.com/REDACTED',
  connectionTimeoutMillis: 10000
}

const runDatabaseFunction = async function (functionToRun) {
  // Connect db
  const client = new Client(postgresOptions)
  await client.connect() // Here’s where it times out after 10 seconds
  // Run function
  // const results = await functionToRun(client)
  // Release db
  await client.end()
  return results
}

async function dbTest () {
  const result = await runDatabaseFunction()
}

dbTest()

10000 毫秒后,它在 await client.connect() 处超时并出现此错误:

(node:80229) UnhandledPromiseRejectionWarning: Error: timeout expired
    at Timeout._onTimeout (/REDACTED/node_modules/pg/lib/client.js:95:26)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)
    at emitUnhandledRejectionWarning (internal/process/promises.js:168:15)
    at processPromiseRejections (internal/process/promises.js:247:11)
    at processTicksAndRejections (internal/process/task_queues.js:94:32)

为什么?!任何提示都是有帮助的。

  • Heroku Postgres 和 ElephantSQL 存在相同的问题。
  • 使用psql 或 Postico for Mac 连接工作正常,连接字符串相同。

【问题讨论】:

  • 可能是防火墙问题。但是如果你使用 psql 连接到同一个 URL 会发生什么?
  • 没有尝试过psql,但 Postico for Mac 使用相同的连接字符串工作得很好。

标签: node.js postgresql node-postgres


【解决方案1】:

原来是pg的旧版本。我将搜索范围扩大到Node.js/Postgres问题,发现this comment

所以升级:

"pg": "^8.7.1",

…我让它为 ElephantSQL 工作。 Heroku Postgres 仍然在 SSL 问题上苦苦挣扎,但是通过将其添加到配置中:

const postgresOptions = {
  // ...
  ssl: { rejectUnauthorized: false }
}

…我也让 Heroku Postgres 工作。

【讨论】:

    【解决方案2】:

    我想你已经错过了这里的 db 端口。

    小建议。根据文档,您可以单独指定客户端配置,我认为这更具可读性和可配置性(如果您愿意,您可以稍后将配置外部化)。所以你可以定义如下配置。

    const client = new Client({
      host: 'my.database-server.com',
      port: 5334,
      user: 'database-user',
      password: 'secretpassword!!',
    })
    

    参考这里:pg Client docs

    除此之外,您必须将一个调用函数传递给runDatabaseFunction(),以便在您的代码中我看不到它的地方可以将它引用为fucntionToRun。否则,尽管您可以通过修复timeout error 成功连接到数据库,但您将获得ReferenceError

    【讨论】:

    • 我像 connectionString: 'postgres://REDACTED:REDACTED@hattie.db.elephantsql.com:5432/REDACTED' 这样添加了端口 5432(与 Postico 客户端相同),但同样的问题。
    • 您确定您的数据库主机已启动并正在运行吗?因为我尝试了连接到我的一个数据库集群的相同代码,并且当我注释掉 const results = await functionToRun(client) 行时它工作正常。因为你没有在那里提供任何函数,你会得到一个引用错误。
    • 是的,因为与 Postico for Mac 连接工作正常。
    【解决方案3】:

    连接字符串是否应该没有“DATABASE_URL=”:

      connectionString: 'postgres://REDACTED:REDACTED@hattie.db.elephantsql.com/REDACTED',
    

    【讨论】:

    • 啊,这是一个错字,它不在真正的代码中,现在更新我的示例。感谢您的发现。但错误仍然存​​在。
    猜你喜欢
    • 2022-07-08
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2019-10-23
    • 2016-11-28
    • 2015-12-13
    相关资源
    最近更新 更多