Skip to content

fix: restore a saved undefined process.exitCode as an explicit 0 - #1086

Open
AntonOfTheWoods wants to merge 1 commit into
electric-sql:mainfrom
pgxsinkit:fix/restore-exit-code-explicit-zero
Open

fix: restore a saved undefined process.exitCode as an explicit 0#1086
AntonOfTheWoods wants to merge 1 commit into
electric-sql:mainfrom
pgxsinkit:fix/restore-exit-code-explicit-zero

Conversation

@AntonOfTheWoods

Copy link
Copy Markdown
Contributor

PGlite saves and restores process.exitCode around engine calls that may run proc_exit(XX) (#init(), close(), execProtocolRaw). On a clean host the saved value is undefined, and under bun assigning undefined to process.exitCode does not clear the current value — depending on the current value it is either a silent no-op or throws TypeError: exitCode must be an integer. The restore therefore fails, and the engine's proc_exit(99) boot sentinel survives to process exit: a fully successful bun process exits with code 99.

Until 0.5.4 this was masked by an accident: close()'s _emscripten_force_exit(0) set an explicit 0 on the way out. #1059 (correctly) made close() restore the previously saved value instead — which removed the incidental reset and exposed the bug for every bun consumer of the 0.5.5 release. Repro, run with bun against @electric-sql/pglite@0.5.5:

import { PGlite } from '@electric-sql/pglite'
const pg = await PGlite.create()
await pg.exec('SELECT 1')
await pg.close()
// prints nothing wrong — but the process exits 99

This also fails any downstream bun test suite that touches PGlite: every test passes and the runner still exits 99.

The fix routes all three restore sites through one helper that restores a saved undefined as an explicit 0, which is equivalent for exit status on every runtime. The added regression test asserts the boot sentinel never remains on process.exitCode; under bun the whole suite additionally force-exits 99 without the fix, so the lane goes red either way.

🤖 Generated with Claude Code

PGlite saves and restores process.exitCode around engine calls that may run
proc_exit(XX). On a clean host the saved value is undefined, and under bun
assigning undefined to process.exitCode does not clear the current value —
depending on the current value it is either a silent no-op or throws
'TypeError: exitCode must be an integer' — so the restore fails and the
engine's proc_exit(99) boot sentinel survives, force-exiting an otherwise
successful host process with code 99.

close() previously masked this: _emscripten_force_exit(0) set an explicit 0
on the way out. Preserving the host exit code across close() (electric-sql#1059) removed
that incidental reset and exposed the bug on every lane — under bun, a fully
green run of the 0.5.5 release now exits 99.

Route all three restore sites through a helper that writes 0 when the saved
value was undefined; that is equivalent for exit status on every runtime.

Repro against the 0.5.5 release, run with bun:

    import { PGlite } from '@electric-sql/pglite'
    const pg = await PGlite.create()
    await pg.exec('SELECT 1')
    await pg.close()
    // process exits 99

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant