fix(lbug): real close on the analyze error path to avoid a hang under skipNativeClose (#2264 review P1-2)

The CLI error handler soft-returns (process.exitCode = 1) instead of forcing
exit, relying on the released native handles to let Node terminate. The earlier
commit made runFullAnalysis's error-path closeLbug skip the native close, leaving
live LadybugDB handles that keep the event loop alive forever — a post-init
analyze failure would hang. Only the SUCCESS path (which guarantees a following
process.exit) skips the native close; the error path now always closes for real.
A late-error close could still abort in the destructor, but that terminates the
process — it does not hang.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JBJomjoTdBV2eveDVq4JMm
This commit is contained in:
Gergo Magyar 2026-06-21 07:41:50 +00:00
parent 8589feb518
commit f3b809624a

View file

@ -1582,9 +1582,14 @@ export async function runFullAnalysis(
/* swallow — surface path is the rethrow below */
}
try {
// Same native-close skip on the error path for CLI callers — they
// process.exit too, and the native close can double-free (#2264).
await closeLbug({ skipNativeClose: options.skipNativeCloseOnExit });
// Real close on the error path — NOT skipNativeClose. The CLI error
// handler soft-returns (process.exitCode = 1) instead of forcing exit, so
// the native handles must be released here or the process would hang on the
// live connection (#2264 review P1-2). A late-error close could still abort
// in LadybugDB's destructor, but that terminates the process — it does not
// hang. Only the success path (which guarantees a following process.exit)
// skips the native close.
await closeLbug();
} catch {
/* swallow */
}