#12656: fix: install unhandled rejection handler before async boot operations
cli
stale
Cluster:
Gateway Error Handling Improvements
## Summary
Fixes #12634
The installUnhandledRejectionHandler() was being called **after** several async operations like ryRouteCli(). If a network error occurred during early boot (before the handler was installed), it would cause an unhandled promise rejection that crashed the gateway.
## The Fix
Move the error handlers to the very first lines of
unCli() to ensure they catch any errors during the entire boot sequence.
### Before
\\\ ypescript
export async function runCli(argv: string[] = process.argv) {
const normalizedArgv = stripWindowsNodeExec(argv);
loadDotEnv({ quiet: true });
// ... more async work ...
if (await tryRouteCli(normalizedArgv)) { // ← Network error here = crash!
return;
}
// Handler installed too late
installUnhandledRejectionHandler();
}
\\\
### After
\\\ ypescript
export async function runCli(argv: string[] = process.argv) {
// Global error handlers FIRST
installUnhandledRejectionHandler();
process.on('uncaughtException', ...);
// Now safe to do async work
const normalizedArgv = stripWindowsNodeExec(argv);
// ...
}
\\\
## Test Plan
- [x] Verified the change is minimal and logically correct
- [ ] CI will run full test suite
🤖 AI-assisted analysis and fix via Clawdbot
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
Moves installation of the global process error handlers (`unhandledRejection` via `installUnhandledRejectionHandler()` and `uncaughtException`) to the very start of `src/cli/run-main.ts:runCli`, before any async boot work (env setup, routing via `tryRouteCli`, and dynamic imports). This ensures early-boot failures (notably transient network errors during routing) are logged/handled consistently rather than surfacing as unhandled promise rejections that crash the process.
<h3>Confidence Score: 4/5</h3>
- This PR is close to safe to merge, with one process-level handler idempotency concern to address.
- The change is small and improves early-boot error coverage, but it also makes `runCli()` install global process handlers earlier and unconditionally; without an idempotency guard, multiple invocations in the same process can accumulate listeners and duplicate exits/logs.
- src/cli/run-main.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#10034: Don't crash gateway on transient unhandled fetch failures
by gigq · 2026-02-06
81.0%
#12987: fix(cli): exit process after successful command completion
by omair445 · 2026-02-10
78.6%
#11101: fix: handle AbortError and WebSocket 1006 in unhandled rejection ha...
by Nipurn123 · 2026-02-07
77.9%
#15306: fix: explicit exit after onboarding command completes
by jeroenbaas · 2026-02-13
76.5%
#3396: Config: gateway.unhandledRejections (warn|exit)
by diegoaledesma · 2026-01-28
76.4%
#19463: fix: suppress undici TLS setSession crash instead of exiting
by abbudjoe · 2026-02-17
75.6%
#4653: fix(gateway): improve crash resilience for mDNS and network errors
by AyedAlmudarra · 2026-01-30
75.2%
#12369: fix: register unhandled rejection handler for Slack monitor
by Yida-Dev · 2026-02-09
75.2%
#17879: fix: prevent Slack auth errors from crashing the entire gateway
by zuyan9 · 2026-02-16
74.6%
#17243: fix(telegram): catch getFile network failures to prevent gateway cr...
by robbyczgw-cla · 2026-02-15
73.2%