Found during the 1.4.0 acceptance pass (#17). Whenever a statement fails at run time, the real error is preceded by a misleading internal error + stack trace:
Error thrown when releasing ended pg.Client Release called on client which has already been released to the pool. Error: Release called on client which has already been released to the pool.
at throwOnDoubleRelease (.../pg-pool/index.js:27:9)
at Client.release (.../pg-pool/index.js:374:9)
at PgPoolExecutor.withClientLock (.../@sqlanvil/cli/bundle.js:40400:24)
...
Dataset creation failed: sqlanvil.bad_syntax [table]
postgres error: Error executing postgres query: syntax error at or near "WHERE"
Repro
Any model whose SQL fails at run time, e.g.:
config { type: "table" }
SELECT FROM WHERE oops
sqlanvil run --actions bad_syntax. Also reproduces on the unnamed-index failure (#31) and presumably any other query error.
Cause
PgPoolExecutor.withClientLock releases the pooled client twice on the error path (release in the try/catch and in a finally, or release-then-release after the client already errored/ended). pg-pool throws throwOnDoubleRelease on the second release.
Impact
The underlying error message itself is clear (good), but the double-release noise + stack trace makes every run-time SQL failure look like an internal crash. Directly undercuts the "clear, actionable errors, not a raw stack trace" MVP criterion (checklist §3/§5). High-frequency: any user with a SQL typo sees it.
Fix direction
In withClientLock, ensure the client is released exactly once (guard with a released flag, or release only in finally and not in the catch). Add a unit/integration test that triggers a query error and asserts no double-release error is emitted.
Found during the 1.4.0 acceptance pass (#17). Whenever a statement fails at run time, the real error is preceded by a misleading internal error + stack trace:
Repro
Any model whose SQL fails at run time, e.g.:
sqlanvil run --actions bad_syntax. Also reproduces on the unnamed-index failure (#31) and presumably any other query error.Cause
PgPoolExecutor.withClientLockreleases the pooled client twice on the error path (release in the try/catch and in afinally, or release-then-release after the client already errored/ended).pg-poolthrowsthrowOnDoubleReleaseon the second release.Impact
The underlying error message itself is clear (good), but the double-release noise + stack trace makes every run-time SQL failure look like an internal crash. Directly undercuts the "clear, actionable errors, not a raw stack trace" MVP criterion (checklist §3/§5). High-frequency: any user with a SQL typo sees it.
Fix direction
In
withClientLock, ensure the client is released exactly once (guard with a released flag, or release only infinallyand not in the catch). Add a unit/integration test that triggers a query error and asserts no double-release error is emitted.