fix(gmail-watcher): catch renewal interval errors#100342
Conversation
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Codex review: needs maintainer review before merge. Reviewed July 6, 2026, 1:21 AM ET / 05:21 UTC. Summary PR surface: Source +2, Tests +118. Total +120 across 2 files. Reproducibility: yes. Source inspection shows current main discards a renewal promise whose callee can reject, and the PR’s focused test/proof path simulates that rejected renewal. Review metrics: none identified. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Next step before merge
Security Review detailsBest possible solution: Merge this narrow foreground renewal catch after normal maintainer review, while leaving broader invalid-OAuth terminal watcher behavior to the existing Gmail watcher health work. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows current main discards a renewal promise whose callee can reject, and the PR’s focused test/proof path simulates that rejected renewal. Is this the best way to solve the issue? Yes. Catching only the renewal call preserves initial startup failure behavior while preventing later transient renewal errors from becoming unhandled rejections; broader terminal OAuth classification belongs to the related watcher-health PR. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 06fbd84d2b1a. Label changesLabel justifications:
Evidence reviewedPR surface: Source +2, Tests +118. Total +120 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (7 earlier review cycles)
|
|
@clawsweeper re-review Addressed the review findings:
Local verification: node_modules/.bin/tsx scripts/proof/gmail-watcher-renewal-catch.mts
node scripts/run-vitest.mjs src/hooks/gmail-watcher.test.ts src/hooks/gmail-ops.test.ts
node_modules/.bin/oxlint src/hooks/gmail-ops.ts src/hooks/gmail-ops.test.ts scripts/proof/gmail-watcher-renewal-catch.mtsAll clean. |
|
🦞🧹 I asked ClawSweeper to review this item again. |
bdb58ce to
31ee824
Compare
|
@clawsweeper re-review Replaced the Vitest-only proof with a real behavior proof that builds fake
PR body updated with the new proof output. |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review Fixed the foreground proof child to exit reliably instead of relying on the spawnSync timeout:
node_modules/.bin/tsx scripts/proof/gmail-watcher-renewal-catch.mtsResult: Regression tests and lint still clean: node scripts/run-vitest.mjs src/hooks/gmail-watcher.test.ts src/hooks/gmail-ops.test.ts
npx oxlint --config .oxlintrc.json src/hooks/gmail-ops.ts src/hooks/gmail-ops.test.ts scripts/proof/gmail-watcher-renewal-catch.mts src/hooks/gmail-watcher.ts src/hooks/gmail-watcher.test.ts |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review Fixed the foreground proof per the latest review:
Branch pushed: |
|
🦞🧹 I asked ClawSweeper to review this item again. |
f601a63 to
f9d6b99
Compare
f9d6b99 to
45ba0db
Compare
45ba0db to
b7f04da
Compare
|
Land-ready verification completed on exact head
The two-file runtime/test repair is ready for the native prepare/merge gates. |
|
Merged via squash.
|
* fix(gmail-watcher): catch renewal interval errors * fix(gmail-ops): catch foreground renewal interval errors; add failing regression test * proof(gmail-watcher): rewrite proof with real fake-gog subprocess for before/after * fix(proof): make gmail-watcher foreground proof child exit reliably * fix(proof): kill fake gog serve child and check spawnSync error in renewal proof * test(gmail): narrow renewal rejection coverage --------- Co-authored-by: Vincent Koc <[email protected]>
* fix(gmail-watcher): catch renewal interval errors * fix(gmail-ops): catch foreground renewal interval errors; add failing regression test * proof(gmail-watcher): rewrite proof with real fake-gog subprocess for before/after * fix(proof): make gmail-watcher foreground proof child exit reliably * fix(proof): kill fake gog serve child and check spawnSync error in renewal proof * test(gmail): narrow renewal rejection coverage --------- Co-authored-by: Vincent Koc <[email protected]>
What Problem This Solves
The Gmail watcher sets up a
setIntervalthat callsstartGmailWatch(runtimeConfig)as a fire-and-forgetvoidexpression in two places:src/hooks/gmail-watcher.ts).openclaw webhooks gmail runpath (src/hooks/gmail-ops.ts).In the foreground path, the local
startGmailWatchhelper does not internally catchrunCommandWithTimeoutfailures. If the periodic Gmail API watch registration rejects, the rejection becomes an unhandled rejection and can crash the foreground process hours after startup.Why This Change Was Made
Added a
.catchto both renewalstartGmailWatchcalls. On rejection, a warning/error is logged and the watcher keeps running, so the next renewal cycle can retry. The initial startup path is unchanged.User Impact
Long-running gateway and foreground Gmail watchers no longer crash on transient Gmail API renewal failures.
Evidence
Real behavior proof builds fake
gogexecutables on disk, prepends them toPATH, and exercises the actual watcher code. The fakegogsucceeds on the initialwatch start, runsserve, then deletes itself so every subsequent renewalwatch startfails withENOENT.Command:
After the fix both paths pass. The proof now also terminates the fake
gog watch servechild before the foreground process exits and fails ifspawnSyncitself errors:Before the fix the foreground path leaks unhandled rejections and the proof fails:
Regression tests still pass: