fix(core): fall back to CLI confirmation when IDE diff open fails#3031
fix(core): fall back to CLI confirmation when IDE diff open fails#3031yiliang114 wants to merge 1 commit intodeps/pr-2728-coretoolschedulerfrom
Conversation
📋 Review SummaryThis PR introduces error handling for the IDE diff open path in 🔍 General Feedback
🎯 Specific Feedback🔵 Low
✅ Highlights
|
| } | ||
| const ideClient = await IdeClient.getInstance(); | ||
| if (!ideClient.isDiffingEnabled()) return; | ||
|
|
There was a problem hiding this comment.
[Suggestion] try-catch 范围过宽 — handleConfirmationResponse 错误被误报为 "IDE diff open failed"
try 块不仅包裹了 IDE diff 操作(IdeClient.getInstance()、openDiff()),还包裹了下游的 handleConfirmationResponse() 调用。由于 openIdeDiffIfEnabled 在调用处(~第 1043 行)是 fire-and-forget 调用,之前 handleConfirmationResponse 的拒绝会作为 unhandled promise rejection 暴露。现在通过在现有 try-catch 内添加 await,这些错误被静默吞掉并记录为 "IDE diff open failed"——这是事实性错误。
建议将 try-catch 缩小到仅覆盖 IDE diff 操作,将 guard 检查和 handleConfirmationResponse 移到 try-catch 之外,失败时 return 回退到 CLI 确认。
| let resolution; | |
| try { | |
| const ideClient = await IdeClient.getInstance(); | |
| if (!ideClient.isDiffingEnabled()) return; | |
| resolution = await ideClient.openDiff( | |
| confirmationDetails.filePath, | |
| confirmationDetails.newContent, | |
| ); | |
| } catch (error) { | |
| if (!signal.aborted) { | |
| debugLogger.warn( | |
| `IDE diff open failed for ${callId}: ${error instanceof Error ? error.message : String(error)}`, | |
| ); | |
| } | |
| return; | |
| } | |
| // Guard: skip if the tool was already handled (e.g. by CLI | |
| // confirmation). Without this check, resolveDiffFromCli | |
| // triggers this handler AND the CLI's onConfirm, causing a | |
| // race where ProceedOnce overwrites ProceedAlways. | |
| const still = this.toolCalls.find( | |
| (c) => c.request.callId === callId && c.status === 'awaiting_approval', | |
| ); | |
| if (!still) return; | |
| if (resolution.status === 'accepted') { | |
| // When content is unchanged, skip the inline modify path so that | |
| // the original tool params (e.g. partial old_string for edit tool) | |
| // are preserved. Mitigate the multi-edit-on-same-file issue (#2702) | |
| // for the common accept-without-edit case. | |
| const userEdited = | |
| resolution.content != null && | |
| resolution.content !== confirmationDetails.newContent; | |
| await this.handleConfirmationResponse( | |
| callId, | |
| confirmationDetails.onConfirm, | |
| ToolConfirmationOutcome.ProceedOnce, | |
| signal, | |
| userEdited ? { newContent: resolution.content } : undefined, | |
| ); | |
| } else { | |
| await this.handleConfirmationResponse( | |
| callId, | |
| confirmationDetails.onConfirm, | |
| ToolConfirmationOutcome.Cancel, | |
| signal, | |
| ); | |
| } |
— glm-5.1 via Qwen Code /review
TLDR
Follow-up fix for the scheduler-based IDE diff refactor in #2728.
When
CoreToolScheduler.openIdeDiffIfEnabled()cannot open the IDE diff because the IDE companion disconnected, the MCP request failed, oropenDiffreturned an error, Qwen Code should fall back to the existing CLI confirmation flow instead of surfacing an unhandled rejection.This is a stacked PR and currently depends on #2728.
Screenshots / Video Demo
N/A — no user-facing change in the normal success path. This only hardens the IDE diff error path and preserves the existing CLI confirmation fallback.
Dive Deeper
Dependency note
deps/pr-2728-coretoolschedulermainProblem
The scheduler-level IDE diff flow introduced in #2728 intentionally opens the IDE diff asynchronously so CLI and IDE confirmation can coexist. However, the IDE-open path did not locally handle failures from
IdeClient.getInstance()/ideClient.openDiff().That meant IDE-side failures such as:
openDifftool errorscould escape as unhandled rejections instead of degrading gracefully to the already-available CLI confirmation path.
Solution
CoreToolScheduler.openIdeDiffIfEnabled()with local error handlingawaiting_approvalstate so the user can still confirm or cancel from the terminalopenDiff()rejection pathReviewer Test Plan
npm run test --workspace=packages/core -- src/core/coreToolScheduler.test.ts.should fall back to CLI confirmation when opening the IDE diff failsopenDiff()rejects, then confirm the tool remains in CLI confirmation flow instead of producing an unhandled rejection.Testing Matrix
Linked issues / bugs