Skip to content

fix: catch unhandled promise rejections in fire-and-forget async calls#102185

Open
zhangLei99586 wants to merge 1 commit into
openclaw:mainfrom
zhangLei99586:fix/unhandled-promise-rejections-fw-20260708
Open

fix: catch unhandled promise rejections in fire-and-forget async calls#102185
zhangLei99586 wants to merge 1 commit into
openclaw:mainfrom
zhangLei99586:fix/unhandled-promise-rejections-fw-20260708

Conversation

@zhangLei99586

@zhangLei99586 zhangLei99586 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fire-and-forget async calls with void keyword silently discard Promise rejections. If the underlying async operation throws (network error, timeout, API failure), the rejected promise becomes an unhandled rejection, which Node.js may terminate the process on in future versions.

Five affected call sites were identified across core and extension code.

Summary

  • Fixes 5 fire-and-forget async call sites where Promise rejections were silently discarded via void, creating unhandled rejection risks in production runtime.
  • Changes are minimal: add .catch() handlers to each call site.

Changes

File Change
src/hooks/gmail-ops.ts void startGmailWatch().catch() with error logging
extensions/feishu/src/monitor.bot-identity.ts void retryBotIdentityProbe().catch() with error logging
extensions/feishu/src/comment-handler.ts void cleanupTypingReaction().catch(() => undefined)
extensions/feishu/src/comment-dispatcher.ts void typingReaction.cleanup().catch(() => undefined)
extensions/telegram/src/bot-message-dispatch.ts .then(() => {}) without .catch() → added .catch(() => undefined)

Evidence

Each change follows the same pattern: replace void asyncCall() with void asyncCall().catch(handler) or add .catch() to an existing .then() chain. Changes are purely defensive — success path behavior is unchanged.

  • src/hooks/gmail-ops.ts - adds error logging via defaultRuntime.error()
  • extensions/feishu/src/monitor.bot-identity.ts - adds error logging via log.warn()
  • extensions/feishu/src/comment-handler.ts - silently swallows (cleanup, non-critical)
  • extensions/feishu/src/comment-dispatcher.ts - silently swallows (cleanup, non-critical)
  • extensions/telegram/src/bot-message-dispatch.ts - silently swallows (best-effort)

Test Plan

  • Existing tests continue to pass — these are defensive error handlers for paths that are not exercised in unit tests.
  • No behavioral change for the success case.

🤖 Generated with Claude Code

@openclaw-barnacle openclaw-barnacle Bot added channel: telegram Channel integration: telegram channel: feishu Channel integration: feishu size: XS triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jul 8, 2026
@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 8, 2026, 9:11 PM ET / 01:11 UTC.

Summary
The branch adds catch handlers around Feishu comment cleanup and bot-identity retry promises, plus a Telegram ack-reaction removal promise.

PR surface: Source +4. Total +4 across 4 files.

Reproducibility: yes. for the remaining blocker by source inspection: the PR catches inside Telegram remove while the shared helper catches remove and calls onError. I did not run a live failure-path probe, and the contributor has not provided after-fix proof for the unhandled-rejection claim.

Review metrics: none identified.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦐 gold shrimp
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Remove the inner Telegram catch or route failures through the existing onError/logAckFailure path.
  • [P1] Add redacted terminal, log, live-output, screenshot, or recording proof showing a rejected background operation is handled after the fix.

Proof guidance:

  • [P1] Needs real behavior proof before merge: No after-fix live run, terminal output, logs, screenshot, recording, or linked artifact is present; the contributor should add redacted proof and update the PR body to trigger a fresh review, or ask a maintainer to comment @clawsweeper re-review if it does not rerun.

Risk before merge

  • [P1] Telegram ack cleanup failures would stop reaching logAckFailure on the changed superseded-dispatch path because the inner catch resolves before removeAckReactionAfterReply can invoke onError.
  • [P1] The contributor has not provided after-fix real behavior proof for the defensive rejection-handling change.

Maintainer options:

  1. Decide the mitigation before merge
    Merge a narrow version that preserves the shared ack-removal onError/logAckFailure path, keeps only defensive catches that do not hide existing diagnostics, and includes redacted live output, terminal output, logs, or a recording proving rejected background work is handled.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] The PR needs contributor follow-up for the Telegram diagnostic regression and missing real behavior proof; ClawSweeper should not take over while the contributor proof gate is unmet.

Security
Cleared: The diff does not change dependencies, workflows, credentials, permissions, package resolution, install scripts, or other security-sensitive surfaces.

Review findings

  • [P2] Preserve ack-removal error reporting — extensions/telegram/src/bot-message-dispatch.ts:2969
Review details

Best possible solution:

Merge a narrow version that preserves the shared ack-removal onError/logAckFailure path, keeps only defensive catches that do not hide existing diagnostics, and includes redacted live output, terminal output, logs, or a recording proving rejected background work is handled.

Do we have a high-confidence way to reproduce the issue?

Yes for the remaining blocker by source inspection: the PR catches inside Telegram remove while the shared helper catches remove and calls onError. I did not run a live failure-path probe, and the contributor has not provided after-fix proof for the unhandled-rejection claim.

Is this the best way to solve the issue?

No. The Feishu catches are a plausible defensive mitigation, but the Telegram change should let the shared helper catch removal failures or explicitly route them through the same onError/logAckFailure path.

Full review comments:

  • [P2] Preserve ack-removal error reporting — extensions/telegram/src/bot-message-dispatch.ts:2969
    This prior blocker is still present. removeAckReactionAfterReply already catches params.remove() and forwards failures to onError; adding .catch(() => undefined) inside this caller makes the helper see success, so real Telegram ack-removal failures stop reaching logAckFailure.
    Confidence: 0.96

Overall correctness: patch is incorrect
Overall confidence: 0.94

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 6630138598b3.

Label changes

Label justifications:

  • P2: This is a normal channel/plugin reliability PR with a concrete diagnostic regression and proof gap but limited blast radius.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: No after-fix live run, terminal output, logs, screenshot, recording, or linked artifact is present; the contributor should add redacted proof and update the PR body to trigger a fresh review, or ask a maintainer to comment @clawsweeper re-review if it does not rerun.
Evidence reviewed

PR surface:

Source +4. Total +4 across 4 files.

View PR surface stats
Area Files Added Removed Net
Source 4 8 4 +4
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 4 8 4 +4

What I checked:

Likely related people:

  • vincentkoc: Current blame ties the shared ack helper, Telegram changed area, and Feishu dispatcher seam to this history, with recent Telegram dispatch work also visible in path history. (role: recent area contributor; confidence: high; commits: eb5d8f85c458, e311943700ae, 4212de9e08d6; files: src/channels/ack-reactions.ts, extensions/telegram/src/bot-message-dispatch.ts, extensions/feishu/src/comment-dispatcher.ts)
  • steipete: GitHub path history shows repeated Feishu monitor/comment-handler refactors and earlier shared channel helper work in the affected area. (role: adjacent channel and Feishu refactor contributor; confidence: medium; commits: b388209eaf72, 58912f8fd842, 827b0de0ce74; files: extensions/feishu/src/comment-handler.ts, extensions/feishu/src/monitor.bot-identity.ts, src/channels/ack-reactions.ts)
  • wittam-01: Feishu comment dispatcher history traces the comment event, comment-thread delivery, and typing-feedback behavior touched by the cleanup changes to this contributor's merged work. (role: Feishu comment feature introducer; confidence: medium; commits: 1b94e8ca14de, ebb72baba3cd, ce0ff42ff5ed; files: extensions/feishu/src/comment-dispatcher.ts, extensions/feishu/src/comment-handler.ts)
  • obviyus: Recent Telegram dispatch file history includes merged work in the same dispatch/progress area near the touched cleanup path. (role: recent Telegram area contributor; confidence: medium; commits: b34c188f8f0d, 3ad465d32b3b, 0ad58848b399; files: extensions/telegram/src/bot-message-dispatch.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (4 earlier review cycles)
  • reviewed 2026-07-08T13:20:10.070Z sha 7a79f54 :: needs real behavior proof before merge. :: [P2] Preserve ack-removal error reporting
  • reviewed 2026-07-08T13:29:48.659Z sha 7a79f54 :: needs real behavior proof before merge. :: [P2] Preserve ack-removal error reporting
  • reviewed 2026-07-08T14:01:50.476Z sha a9f355b :: needs real behavior proof before merge. :: [P1] Remove the duplicate progress-summary import | [P2] Preserve ack-removal error reporting
  • reviewed 2026-07-09T01:04:47.504Z sha 3c58abd :: needs real behavior proof before merge. :: [P2] Preserve ack-removal error reporting

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels Jul 8, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jul 8, 2026
@zhangLei99586
zhangLei99586 force-pushed the fix/unhandled-promise-rejections-fw-20260708 branch from 7a79f54 to 65d4bb3 Compare July 8, 2026 13:45
@openclaw-barnacle openclaw-barnacle Bot added channel: nostr Channel integration: nostr size: S and removed size: XS labels Jul 8, 2026
@clawsweeper clawsweeper Bot removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 8, 2026
@zhangLei99586
zhangLei99586 force-pushed the fix/unhandled-promise-rejections-fw-20260708 branch from 65d4bb3 to a9f355b Compare July 8, 2026 13:49
@openclaw-barnacle openclaw-barnacle Bot added size: XS and removed channel: nostr Channel integration: nostr size: S labels Jul 8, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 8, 2026
Adds .catch() handlers to five async call sites where Promise rejections
were silently discarded via `void`, creating unhandled rejection risks:
- gmail-ops.ts: startGmailWatch renew timer callback
- feishu/monitor.bot-identity.ts: retryBotIdentityProbe fire-and-forget
- feishu/comment-handler.ts: cleanupTypingReaction fire-and-forget
- feishu/comment-dispatcher.ts: typingReaction.cleanup fire-and-forget
- telegram/bot-message-dispatch.ts: reactionApi remove promise chain

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@zhangLei99586
zhangLei99586 force-pushed the fix/unhandled-promise-rejections-fw-20260708 branch from a9f355b to 3c58abd Compare July 9, 2026 00:59
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: feishu Channel integration: feishu channel: telegram Channel integration: telegram P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XS stale Marked as stale due to inactivity status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant