Skip to content

Close the connection when fetching array types fails - fixes #1192 - #1265

Open
asharrahman02 wants to merge 2 commits into
porsager:masterfrom
asharrahman02:fix-fetch-array-types-rejection
Open

asharrahman02 wants to merge 2 commits into
porsager:masterfrom
asharrahman02:fix-fetch-array-types-rejection

Conversation

@asharrahman02

Copy link
Copy Markdown

Fixes #1192, fixes #1205 (also the original #279)

ReadyForQuery drops the promise returned by fetchArrayTypes(), so when the internal pg_type query fails (statement timeout, cancellation, a pooler killing a fresh backend, sql.end({ timeout }) during startup) the rejection is unhandled and Node exits — even though the user's query is rejected and caught normally. Catching it alone isn't enough: the connection would then be handed to the pool without array parsers, and arrays come back as strings like '{1,2}'.

This change:

  • Awaits the types query through .catch(), so its rejection is always handled.
  • Wraps the types query's reject (the same way fetchState() sets resolve) to set needsTypes again synchronously. ReadyForQuery then closes the connection instead of opening it, before onopen() can give it to queued work. The next connection fetches types again.
  • Rejects a waiting sql.reserve() with the server's error. ReadyForQuery removes the reserve from initial before the fetch, so errored() never reaches it, and before this change the reserve was resolved with a connection that had no array types.

The user's query still gets the original server error, and the success path is unchanged.

  • The first commit adds three tests that revoke select on pg_catalog.pg_type for the test database (restored in each test): a first query rejects with 42501 and a later array query on the same client parses {1,2} as an array; two queued queries on max: 1 both reject; a waiting reserve() rejects. Without the fix, the suite crashes on the unhandled 42501. With --unhandled-rejections=warn, the first test fails with '42501,true' != '42501,false' (the array comes back as a string).
  • The second commit is the fix, in src/ only; cjs/, cf/ and deno/ are left for the build.
  • The ESM and CJS suites pass (267/267) on Node 20 against PostgreSQL 17. Deno was not run.

This is the same approach as #1231, which was closed by its author, but it doesn't depend on #1230. We run this change as a patch on 3.4.9 in production.

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

Labels

None yet

Projects

None yet

1 participant