现状
全量 review 发现前端事件监听生命周期和错误处理不一致:
-
Review stream listener 绑定在 ReviewPanel 生命周期上。
src/review/ReviewPanel.vue:43 mount 时 init()。
src/review/ReviewPanel.vue:47 unmount 时 unlisten。
src/App.vue:163 到 src/App.vue:213 中 settings/monitor 是互斥视图,切到 Settings 会卸载 ReviewPanel。
src/review/useReviewStore.ts:267 明确后端不 replay past deltas。
因此切到 Settings 期间后端继续 emit 的 review delta 没有任何全局 listener 接收,回来后输出缺段。
-
PR listener 注册失败不会进入 UI error 状态。
src/pr/usePrStore.ts:95 直接 await subscribe()。
src/pr/PollControls.vue:23 无 catch。
src/pr/usePrStore.ts:105 成功 poll 后依赖 prs:updated listener 清 loading。
如果 listener 注册失败,手动拉取成功后可能一直 loading。
-
stop 成功后没有本地“停止中”反馈。
src/review/useReviewStore.ts:253 成功路径只 await stopReview(id)。
- 后端
src-tauri/src/review/session.rs:119 已把 Running 改成 Interrupting。
- 前端仍显示 running,停止按钮仍可点,直到 terminal event 到达。
三维根因
- 代码:事件订阅归属在局部 UI 组件,而事件源是 app/backend 生命周期。
- 架构:store 是 singleton,但 listener 不是 singleton;部分事件可 snapshot 恢复,review stream 不可恢复。
- 历史:PR 列表后来补了
get_prs 快照兜底,review stream 仍依赖实时 listener。
影响
- 用户切视图会丢 review 输出,且没有明确提示。
- PR listener 注册失败后可能出现永久 loading。
- stop 操作缺少 interrupting 反馈,用户可能重复点击。
修复方向
- 最小方案:PR
init() catch listener 注册失败,设置 error、loading=false,返回 noop unlisten;stop 成功后刷新 sessions 或设置本地 interrupting。
- 彻底方案:把 review listener 提升到 App 生命周期或模块单例,避免视图切换 unlisten。
- 重构方案:后端为每个 review session 保留可 replay buffer,前端 focus/reattach 时补历史。
Files
src/App.vue:163
src/App.vue:212
src/review/ReviewPanel.vue:43
src/review/ReviewPanel.vue:47
src/review/useReviewStore.ts:253
src/review/useReviewStore.ts:267
src/pr/usePrStore.ts:95
src/pr/usePrStore.ts:105
src/pr/PollControls.vue:23
src-tauri/src/review/session.rs:119
Source
Discovered via full-project review with 6 subagents on 2026-06-17.
现状
全量 review 发现前端事件监听生命周期和错误处理不一致:
Review stream listener 绑定在
ReviewPanel生命周期上。src/review/ReviewPanel.vue:43mount 时init()。src/review/ReviewPanel.vue:47unmount 时unlisten。src/App.vue:163到src/App.vue:213中 settings/monitor 是互斥视图,切到 Settings 会卸载 ReviewPanel。src/review/useReviewStore.ts:267明确后端不 replay past deltas。因此切到 Settings 期间后端继续 emit 的 review delta 没有任何全局 listener 接收,回来后输出缺段。
PR listener 注册失败不会进入 UI error 状态。
src/pr/usePrStore.ts:95直接 awaitsubscribe()。src/pr/PollControls.vue:23无 catch。src/pr/usePrStore.ts:105成功 poll 后依赖prs:updatedlistener 清loading。如果 listener 注册失败,手动拉取成功后可能一直 loading。
stop 成功后没有本地“停止中”反馈。
src/review/useReviewStore.ts:253成功路径只 awaitstopReview(id)。src-tauri/src/review/session.rs:119已把 Running 改成 Interrupting。三维根因
get_prs快照兜底,review stream 仍依赖实时 listener。影响
修复方向
init()catch listener 注册失败,设置error、loading=false,返回 noop unlisten;stop 成功后刷新 sessions 或设置本地 interrupting。Files
src/App.vue:163src/App.vue:212src/review/ReviewPanel.vue:43src/review/ReviewPanel.vue:47src/review/useReviewStore.ts:253src/review/useReviewStore.ts:267src/pr/usePrStore.ts:95src/pr/usePrStore.ts:105src/pr/PollControls.vue:23src-tauri/src/review/session.rs:119Source
Discovered via full-project review with 6 subagents on 2026-06-17.