Skip to content

fix(gemini): prevent unhandled rejection when bootstrap fails#1769

Merged
piorpua merged 2 commits intomainfrom
fix/sentry-ELECTRON-5B
Mar 27, 2026
Merged

fix(gemini): prevent unhandled rejection when bootstrap fails#1769
piorpua merged 2 commits intomainfrom
fix/sentry-ELECTRON-5B

Conversation

@kaizhou-lab
Copy link
Copy Markdown
Collaborator

Summary

  • Attach no-op .catch(() => {}) to the deferred bootstrap promise in both GeminiAgent (worker) and GeminiAgentManager (main process) constructors
  • When initialize() rejects (e.g. missing Google OAuth credentials), the rejection no longer fires as an unhandledRejection event — the error still propagates when send() / sendMessage() later awaits the promise
  • Add unit tests verifying the rejection-handling pattern

Closes #1768

Sentry issue: ELECTRON-5B (76 events, last seen today on v1.9.1)

Changed files

File Change
src/process/agent/gemini/index.ts Add .catch(() => {}) after this.bootstrap = this.initialize()
src/process/task/GeminiAgentManager.ts Add .catch(() => {}) after this.bootstrap = this.createBootstrap()
tests/unit/geminiBootstrapRejection.test.ts New test: verifies no unhandled rejection + error still propagates

Verification

  • Unit tests pass (3/3 new tests)
  • Type check passes (tsc --noEmit)
  • Lint and format clean
  • Pre-existing test failure in previewFileWatch.dom.test.ts is unrelated

Test plan

  • bun run test — new tests pass
  • bunx tsc --noEmit — no type errors
  • Deploy to staging and verify ELECTRON-5B stops recurring in Sentry

Attach no-op .catch() to the deferred bootstrap promise in both
GeminiAgent (worker) and GeminiAgentManager (main process) constructors.
Without this, when initialize() rejects (e.g. missing Google OAuth
credentials), the rejection fires as an unhandledRejection before any
caller awaits the promise — propagating to the renderer as a Sentry
error.  The error still surfaces when send() / sendMessage() later
awaits bootstrap.

Fixes ELECTRON-5B
@kaizhou-lab kaizhou-lab marked this pull request as ready for review March 27, 2026 02:46
@piorpua piorpua added bot:reviewing Review in progress (mutex) and removed bot:reviewing Review in progress (mutex) labels Mar 27, 2026
@piorpua piorpua added bot:reviewing Review in progress (mutex) and removed bot:reviewing Review in progress (mutex) labels Mar 27, 2026
@piorpua
Copy link
Copy Markdown
Contributor

piorpua commented Mar 27, 2026

Code Review:fix(gemini): prevent unhandled rejection when bootstrap fails (#1769)

变更概述

本 PR 修复了 Sentry issue ELECTRON-5B:GeminiAgent(worker)和 GeminiAgentManager(主进程)在构造函数中将 bootstrap 初始化的 Promise 赋值给 this.bootstrap 后,若 initialize() / createBootstrap() 拒绝(如缺少 Google OAuth 凭证),会触发 Node.js 的 unhandledRejection 事件。解决方案为在赋值后立即附加 bootstrap.catch(() => {}),阻止运行时报告"未处理"状态,而错误仍会在 send() / sendMessage() 后续 await this.bootstrap 时正常抛出。同时新增了 3 个单元测试验证此行为。


方案评估

结论:✅ 方案合理

.catch(() => {}) 是 Node.js 中防止 unhandled rejection 的标准惯用做法:附加无操作 catch handler 告知运行时该 Promise 已有处理者,而原 Promise 引用保持不变——后续调用方 await this.bootstrap 仍会收到拒绝。方案最小化、无副作用,与项目现有 IPC / worker 架构边界无交叉。


问题清单

✅ 未发现明显问题,代码质量良好。

以下几点仅作信息说明(不影响合并):

测试文件中的时序假设tests/unit/geminiBootstrapRejection.test.ts,第 35 行)

await new Promise((resolve) => setTimeout(resolve, 50));

第一个测试用 50ms 等待来"给 Node 时间检测 unhandledRejection"。实际上 Node.js 在当前 microtask queue 耗尽后下一个 tick 即可确定 unhandled rejection,现有等待时间足够宽松,不构成实际 flaky 风险。

Lint 警告均为已有代码oxlint 输出的 10 条警告(no-shadowno-unused-vars 等)全部来自 PR 未修改的既有代码行,本次改动不引入任何新警告。


汇总

本 PR 无需修复任何问题。

结论

批准合并 — 修复方案正确、最小化,单元测试覆盖关键行为,CI 全部通过。


本报告由本地 pr-review skill 生成,包含完整项目上下文,无截断限制。

@piorpua
Copy link
Copy Markdown
Contributor

piorpua commented Mar 27, 2026

✅ 已自动 review,无阻塞性问题,正在触发自动合并。

@piorpua piorpua merged commit 495cff1 into main Mar 27, 2026
15 of 17 checks passed
@piorpua piorpua deleted the fix/sentry-ELECTRON-5B branch March 27, 2026 03:20
@piorpua piorpua added bot:done Auto-merged by bot and removed bot:reviewing Review in progress (mutex) labels Mar 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:done Auto-merged by bot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: unhandled promise rejection in GeminiAgent bootstrap (ELECTRON-5B)

2 participants