Skip to content

Commit f8bd001

Browse files
committed
fix: improve multi-file diff error handling and UI feedback
- Fix nested array issue in multi-file-search-replace strategy - Consolidate diff error reporting to single message - Fix infinite spinner on single file diff failures
1 parent ec9b27d commit f8bd001

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

src/core/diff/strategies/multi-file-search-replace.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,13 @@ Each file requires its own path, start_line, and diff elements.
410410
resultContent = singleResult.content
411411
successCount++
412412
} else {
413-
allFailParts.push(singleResult)
413+
// If singleResult has failParts, push those directly to avoid nesting
414+
if (singleResult.failParts && singleResult.failParts.length > 0) {
415+
allFailParts.push(...singleResult.failParts)
416+
} else {
417+
// Otherwise push the single result itself
418+
allFailParts.push(singleResult)
419+
}
414420
}
415421
}
416422

src/core/tools/multiApplyDiffTool.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ Expected structure:
161161
Original error: ${errorMessage}`
162162
throw new Error(detailedError)
163163
}
164-
165164
} else if (legacyPath && typeof legacyDiffContent === "string") {
166165
// Handle legacy parameters (old way)
167166
usingLegacyParams = true
@@ -221,6 +220,7 @@ Original error: ${errorMessage}`
221220
try {
222221
// First validate all files and prepare for batch approval
223222
const operationsToApprove: OperationResult[] = []
223+
const allDiffErrors: string[] = [] // Collect all diff errors
224224

225225
for (const operation of operations) {
226226
const { path: relPath, diff: diffItems } = operation
@@ -427,6 +427,9 @@ Original error: ${errorMessage}`
427427
continue
428428
}
429429

430+
// Collect error for later reporting
431+
allDiffErrors.push(`${relPath} - Diff ${i + 1}: ${failPart.error}`)
432+
430433
const errorDetails = failPart.details ? JSON.stringify(failPart.details, null, 2) : ""
431434
formattedError += `<error_details>
432435
Diff ${i + 1} failed for file: ${relPath}
@@ -471,6 +474,17 @@ ${errorDetails ? `\nTechnical details:\n${errorDetails}\n` : ""}
471474
}
472475
cline.recordToolError("apply_diff", formattedError)
473476
results.push(formattedError)
477+
478+
// For single file operations, we need to send a complete message to stop the spinner
479+
if (operationsToApprove.length === 1) {
480+
const sharedMessageProps: ClineSayTool = {
481+
tool: "appliedDiff",
482+
path: getReadablePath(cline.cwd, relPath),
483+
diff: diffItems.map((item) => item.content).join("\n\n"),
484+
}
485+
// Send a complete message (partial: false) to update the UI and stop the spinner
486+
await cline.ask("tool", JSON.stringify(sharedMessageProps), false).catch(() => {})
487+
}
474488
}
475489
continue
476490
}
@@ -559,6 +573,11 @@ ${errorDetails ? `\nTechnical details:\n${errorDetails}\n` : ""}
559573
results.push(...filteredOperationErrors)
560574
}
561575

576+
// Report all diff errors at once if any
577+
if (allDiffErrors.length > 0) {
578+
await cline.say("diff_error", allDiffErrors.join("\n"))
579+
}
580+
562581
// Push the final result combining all operation results
563582
pushToolResult(results.join("\n\n"))
564583
return

0 commit comments

Comments
 (0)