Skip to content

fix(cloudflare): emit close when the socket closed promise rejects - #3834

Open
princejain756 wants to merge 1 commit into
brianc:masterfrom
princejain756:fix-cloudflare-close-on-reject
Open

princejain756 wants to merge 1 commit into
brianc:masterfrom
princejain756:fix-cloudflare-close-on-reject

Conversation

@princejain756

Copy link
Copy Markdown

workerd rejects a socket's closed promise with undefined when socket.close() runs in the same turn as the read that reaches the end of a stream the server closed (cloudflare/workerd#6479). pg hits this after pg_terminate_backend() during a query: the query rejects, client.end() runs close() right after _listen() reaches the stream end, closed rejects, and the handler emits error but never close. Connection waits on the stream's close to emit end, so client.end() never resolves. On top of that, the error carries undefined, which crashes reportStreamError reading error.code.

Two changes to match net.Socket, which always emits close after error:

  • a rejected closed promise now emits close (after error, same order as net.Socket)
  • the error is skipped when the rejection follows end(), since the socket was being closed anyway; a rejected close() emits close the same way

Reproduced with stubbed closed promises in pg-esm-test/pg-cloudflare.test.js: a mid-session rejection still emits error then close in that order, and end() followed by a rejection emits close with no spurious error. 6/6 tests pass and both new cases fail on the old build.

Fixes #3822

workerd rejects the socket closed promise with undefined when close()
runs in the same turn as the read that reaches a server-closed stream
end (cloudflare/workerd#6479). The handler forwarded that as error and
never emitted close, so Connection's end handler never fired and
client.end() hung; pg also crashed reading error.code off the
undefined rejection.

Match net.Socket instead: a rejected closed promise still emits
close, and the error is skipped when the rejection follows end() since
the socket was being closed anyway. A failed close() call now surfaces
close the same way.

Fixes brianc#3822
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pg-cloudflare: no 'close' when workerd rejects the socket's closed promise, so client.end() never resolves

1 participant