From f0ec11feb67bf3b87edefbabfa2bb89f9d860104 Mon Sep 17 00:00:00 2001 From: Saadanjum0 <160885369+Saadanjum0@users.noreply.github.com> Date: Tue, 20 Oct 2026 14:07:18 +0500 Subject: [PATCH] fix(pg-cloudflare): emit close after the socket's closed promise rejects --- packages/pg-cloudflare/src/index.ts | 10 +++++++++- packages/pg-esm-test/pg-cloudflare.test.js | 23 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/pg-cloudflare/src/index.ts b/packages/pg-cloudflare/src/index.ts index 527b433f5..366752d1e 100644 --- a/packages/pg-cloudflare/src/index.ts +++ b/packages/pg-cloudflare/src/index.ts @@ -163,7 +163,15 @@ export class CloudflareSocket extends EventEmitter { this._upgraded = true } }) - .catch((e) => this.emit('error', e)) + .catch((e) => { + // workerd can reject `closed` with `undefined` + this.emit('error', e ?? new Error('Socket closed with an error')) + // like net.Socket, follow the error with 'close' so the connection ends + if (this._cfSocket === socket) { + this._cfSocket = null + this.emit('close') + } + }) } } diff --git a/packages/pg-esm-test/pg-cloudflare.test.js b/packages/pg-esm-test/pg-cloudflare.test.js index 683229158..6c53f50e7 100644 --- a/packages/pg-esm-test/pg-cloudflare.test.js +++ b/packages/pg-esm-test/pg-cloudflare.test.js @@ -19,6 +19,29 @@ describe('pg-cloudflare', () => { assert.doesNotThrow(() => socket.end()) }) + it('should emit error then close when the closed promise rejects', async () => { + const socket = new CloudflareSocket() + const underlyingSocket = { closed: Promise.reject(undefined) } + socket._cfSocket = underlyingSocket + + const events = [] + socket.on('error', (error) => events.push(error)) + await new Promise((resolve, reject) => { + const timer = setTimeout(() => reject(new Error('close event was not emitted')), 100) + socket.once('close', () => { + clearTimeout(timer) + events.push('close') + resolve() + }) + socket._addClosedHandler() + }) + + assert.equal(events.length, 2) + assert.ok(events[0] instanceof Error) + assert.equal(events[1], 'close') + assert.equal(socket._cfSocket, null) + }) + it('should call the write(data, callback) callback exactly once', async () => { const socket = new CloudflareSocket() socket._cfWriter = { write: () => Promise.resolve() }