From 5656f830d617cb9a4330c0ca1e978b018061e085 Mon Sep 17 00:00:00 2001 From: Charmander <~@charmander.me> Date: Wed, 13 May 2026 22:01:31 -0700 Subject: [PATCH 1/3] test: unintended listener after no-op `Client#end` callback --- packages/pg/test/integration/client/api-tests.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/pg/test/integration/client/api-tests.js b/packages/pg/test/integration/client/api-tests.js index ab7ad6db8..2b0c3f85b 100644 --- a/packages/pg/test/integration/client/api-tests.js +++ b/packages/pg/test/integration/client/api-tests.js @@ -230,6 +230,21 @@ suite.test('callback is fired once and only once', function (done) { ) }) +suite.test('no-op Client#end callback is called exactly once', (done) => { + const client = new helper.Client() + let called = false + + client.end(() => { + assert(!called) + called = true + + client.connect((err) => { + assert.ifError(err) + client.end(done) + }) + }) +}) + suite.test('can provide callback and config object', function (done) { const pool = new pg.Pool() pool.connect( From 7a97d7e943e3f2c7801e1cd78e0ed8c3165ac3b2 Mon Sep 17 00:00:00 2001 From: Charmander <~@charmander.me> Date: Wed, 13 May 2026 22:02:46 -0700 Subject: [PATCH 2/3] fix: `Client#end` callback being called multiple times when first is no-op (and unwanted retained listener even when not called multiple times) --- packages/pg/lib/client.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/pg/lib/client.js b/packages/pg/lib/client.js index 3bfffc7d2..3525cf5ac 100644 --- a/packages/pg/lib/client.js +++ b/packages/pg/lib/client.js @@ -716,6 +716,7 @@ class Client extends EventEmitter { if (!this.connection._connecting || this._ended) { if (cb) { cb() + return } else { return this._Promise.resolve() } From 6f543f4a65134b0dce466158bb2fe60ed6eabaa6 Mon Sep 17 00:00:00 2001 From: Charmander <~@charmander.me> Date: Wed, 13 May 2026 22:16:41 -0700 Subject: [PATCH 3/3] fix: Prevent multiple callbacks in pg/native `Client#end`, and align pre-connect behaviour closer to pg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As usual, the native client is extra full of bugs and inconsistencies, so this is just “good enough”. --- packages/pg/lib/native/client.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/pg/lib/native/client.js b/packages/pg/lib/native/client.js index 6df471b83..fa17d9f65 100644 --- a/packages/pg/lib/native/client.js +++ b/packages/pg/lib/native/client.js @@ -249,8 +249,10 @@ Client.prototype.end = function (cb) { this._ending = true - if (!this._connected) { - this.once('connect', this.end.bind(this, cb)) + if (this._connecting && !this._connected) { + this.once('connect', () => { + this.end(() => {}) + }) } let result if (!cb) {