Commit bb23dd2
authored
fix(kernel-cli): log fatal exits from daemon-entry before terminating (#966)
## Summary
- Add process-level handlers in `daemon-entry.ts` for
`uncaughtException`, `unhandledRejection`, `SIGHUP`, and `exit`.
- Each handler synchronously appends a line to `daemon.log` before the
process exits.
- Handlers install at module load, before `main()` runs, so early
kernel-init failures also leave a fingerprint.
## Why
`daemon-entry` runs with `stdio: 'ignore'` under the CLI spawner (see
`daemon-spawn.ts`). Node's default behaviour on `uncaughtException` /
`unhandledRejection` (print stack to stderr, exit 1) therefore writes to
nowhere, and the operator sees only that the daemon vanished — no trace
in `~/.ocap*/daemon.log`.
I've hit two silent daemon deaths in the last few weeks (matcher daemon
disappearing mid-rehearsal, services daemon disappearing between
registration and the next call), and in both cases the log ended cleanly
on the last successful message with no shutdown line, no error, no stack
trace. Debugging cost real time each time.
With this change, every terminating path now leaves at least one line:
```
[timestamp] [error] Uncaught exception (about to exit): <stack>
[timestamp] [error] Process exiting (code=1).
```
or
```
[timestamp] [error] SIGHUP received; exiting.
[timestamp] [error] Process exiting (code=0).
```
Log-write itself is wrapped in try/catch so a broken log file doesn't
mask the original exit cause.
## Test plan
- [x] `yarn workspace @metamask/kernel-cli test:dev:quiet --run` — all
package tests pass.
- [x] `yarn workspace @metamask/kernel-cli lint` — clean.
- [ ] CI green.
- [ ] Manual (in a downstream branch): induce an uncaught exception in a
scratch daemon under a temp \$OCAP_HOME, confirm the log line lands and
the process exits 1.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Observability-only changes to daemon exit paths; SIGHUP now logs and
exits 0 explicitly instead of the default silent terminate, with no auth
or data-handling impact.
>
> **Overview**
> **Daemon fatal-path visibility** when the CLI spawns `daemon-entry`
with `stdio: 'ignore'`: uncaught errors and signals no longer vanish
with no record in `daemon.log`.
>
> `daemon-entry` now builds the file logger at **module load** (before
`main()`), registers `installFatalHandlers()` immediately, and logs then
exits on **`uncaughtException`**, **`unhandledRejection`**, and
**`SIGHUP`**, with an **`exit`** handler that always writes a final
line. The log transport switches from dynamic `require('node:fs')` to
**`appendFileSync`** so fatal handlers flush synchronously. CHANGELOG
documents the fix under Unreleased.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
70b96eb. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->1 parent f309811 commit bb23dd2
2 files changed
Lines changed: 77 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
| 24 | + | |
23 | 25 | | |
24 | 26 | | |
25 | 27 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
13 | 32 | | |
14 | 33 | | |
15 | 34 | | |
| |||
19 | 38 | | |
20 | 39 | | |
21 | 40 | | |
22 | | - | |
23 | 41 | | |
24 | 42 | | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | 43 | | |
32 | 44 | | |
33 | 45 | | |
| |||
129 | 141 | | |
130 | 142 | | |
131 | 143 | | |
132 | | - | |
| 144 | + | |
133 | 145 | | |
134 | 146 | | |
135 | | - | |
136 | | - | |
137 | | - | |
| 147 | + | |
138 | 148 | | |
139 | 149 | | |
140 | 150 | | |
141 | | - | |
| 151 | + | |
142 | 152 | | |
143 | 153 | | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
0 commit comments