From 3e3cc65d422248aabefc520ed7249a6a75c1797b Mon Sep 17 00:00:00 2001 From: Stephen O'Brien Date: Fri, 7 Aug 2026 17:44:05 -0400 Subject: [PATCH] Fix unbounded reconnect loop when all hosts fail during connect --- src/connection.js | 9 +++++++-- tests/index.js | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/connection.js b/src/connection.js index 1b1cccde..3e2560e2 100644 --- a/src/connection.js +++ b/src/connection.js @@ -447,9 +447,14 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose socket.removeAllListeners() socket = null - if (initial) - return reconnect() + if (initial) { + if (options.host[++retries]) + return reconnect() + + errored(Errors.connection('CONNECTION_CLOSED', options, socket)) + } + retries = 0 !hadError && (query || sent.length) && error(Errors.connection('CONNECTION_CLOSED', options, socket)) closedTime = performance.now() hadError && options.shared.retries++ diff --git a/tests/index.js b/tests/index.js index 23e6c4d4..354018ff 100644 --- a/tests/index.js +++ b/tests/index.js @@ -1060,6 +1060,25 @@ t('Connection errors are caught using begin()', { ] }) +t('Connection errors are caught when all hosts fail', { + timeout: 2 +}, async() => { + let error + try { + const sql = postgres({ host: ['localhost', 'localhost'], port: [1, 1] }) + + await sql`select 1` + } catch (err) { + error = err + } + + return [ + true, + error.code === 'ECONNREFUSED' || + error.message === 'Connection refused (os error 61)' + ] +}) + t('dynamic table name', async() => { await sql`create table test(a int)` return [