mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-22 18:24:21 +01:00
fix: handle parsePatch errors in TUI to prevent crashes
Wrap parsePatch calls in try-catch blocks to gracefully handle malformed diffs that can occur when undoing after tool_use/tool_result errors or cancelled prompts. Prevents TUI from crashing with 'Added line count did not match for hunk' error. Fixes #3700
This commit is contained in:
@@ -480,22 +480,26 @@ export function Session() {
|
|||||||
const diffText = s.revert?.diff || ""
|
const diffText = s.revert?.diff || ""
|
||||||
if (!diffText) return []
|
if (!diffText) return []
|
||||||
|
|
||||||
const patches = parsePatch(diffText)
|
try {
|
||||||
return patches.map((patch) => {
|
const patches = parsePatch(diffText)
|
||||||
const filename = patch.newFileName || patch.oldFileName || "unknown"
|
return patches.map((patch) => {
|
||||||
const cleanFilename = filename.replace(/^[ab]\//, "")
|
const filename = patch.newFileName || patch.oldFileName || "unknown"
|
||||||
return {
|
const cleanFilename = filename.replace(/^[ab]\//, "")
|
||||||
filename: cleanFilename,
|
return {
|
||||||
additions: patch.hunks.reduce(
|
filename: cleanFilename,
|
||||||
(sum, hunk) => sum + hunk.lines.filter((line) => line.startsWith("+")).length,
|
additions: patch.hunks.reduce(
|
||||||
0,
|
(sum, hunk) => sum + hunk.lines.filter((line) => line.startsWith("+")).length,
|
||||||
),
|
0,
|
||||||
deletions: patch.hunks.reduce(
|
),
|
||||||
(sum, hunk) => sum + hunk.lines.filter((line) => line.startsWith("-")).length,
|
deletions: patch.hunks.reduce(
|
||||||
0,
|
(sum, hunk) => sum + hunk.lines.filter((line) => line.startsWith("-")).length,
|
||||||
),
|
0,
|
||||||
}
|
),
|
||||||
})
|
}
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
})()
|
})()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -1245,58 +1249,63 @@ ToolRegistry.register<typeof EditTool>({
|
|||||||
const diff = createMemo(() => {
|
const diff = createMemo(() => {
|
||||||
const diff = props.metadata.diff ?? props.permission["diff"]
|
const diff = props.metadata.diff ?? props.permission["diff"]
|
||||||
if (!diff) return null
|
if (!diff) return null
|
||||||
const patches = parsePatch(diff)
|
|
||||||
if (patches.length === 0) return null
|
|
||||||
|
|
||||||
const patch = patches[0]
|
try {
|
||||||
const oldLines: string[] = []
|
const patches = parsePatch(diff)
|
||||||
const newLines: string[] = []
|
if (patches.length === 0) return null
|
||||||
|
|
||||||
for (const hunk of patch.hunks) {
|
const patch = patches[0]
|
||||||
let i = 0
|
const oldLines: string[] = []
|
||||||
while (i < hunk.lines.length) {
|
const newLines: string[] = []
|
||||||
const line = hunk.lines[i]
|
|
||||||
|
|
||||||
if (line.startsWith("-")) {
|
for (const hunk of patch.hunks) {
|
||||||
const removedLines: string[] = []
|
let i = 0
|
||||||
while (i < hunk.lines.length && hunk.lines[i].startsWith("-")) {
|
while (i < hunk.lines.length) {
|
||||||
removedLines.push("- " + hunk.lines[i].slice(1))
|
const line = hunk.lines[i]
|
||||||
|
|
||||||
|
if (line.startsWith("-")) {
|
||||||
|
const removedLines: string[] = []
|
||||||
|
while (i < hunk.lines.length && hunk.lines[i].startsWith("-")) {
|
||||||
|
removedLines.push("- " + hunk.lines[i].slice(1))
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
const addedLines: string[] = []
|
||||||
|
while (i < hunk.lines.length && hunk.lines[i].startsWith("+")) {
|
||||||
|
addedLines.push("+ " + hunk.lines[i].slice(1))
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
const maxLen = Math.max(removedLines.length, addedLines.length)
|
||||||
|
for (let j = 0; j < maxLen; j++) {
|
||||||
|
oldLines.push(removedLines[j] ?? "")
|
||||||
|
newLines.push(addedLines[j] ?? "")
|
||||||
|
}
|
||||||
|
} else if (line.startsWith("+")) {
|
||||||
|
const addedLines: string[] = []
|
||||||
|
while (i < hunk.lines.length && hunk.lines[i].startsWith("+")) {
|
||||||
|
addedLines.push("+ " + hunk.lines[i].slice(1))
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const added of addedLines) {
|
||||||
|
oldLines.push("")
|
||||||
|
newLines.push(added)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
oldLines.push(" " + line.slice(1))
|
||||||
|
newLines.push(" " + line.slice(1))
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
const addedLines: string[] = []
|
|
||||||
while (i < hunk.lines.length && hunk.lines[i].startsWith("+")) {
|
|
||||||
addedLines.push("+ " + hunk.lines[i].slice(1))
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxLen = Math.max(removedLines.length, addedLines.length)
|
|
||||||
for (let j = 0; j < maxLen; j++) {
|
|
||||||
oldLines.push(removedLines[j] ?? "")
|
|
||||||
newLines.push(addedLines[j] ?? "")
|
|
||||||
}
|
|
||||||
} else if (line.startsWith("+")) {
|
|
||||||
const addedLines: string[] = []
|
|
||||||
while (i < hunk.lines.length && hunk.lines[i].startsWith("+")) {
|
|
||||||
addedLines.push("+ " + hunk.lines[i].slice(1))
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const added of addedLines) {
|
|
||||||
oldLines.push("")
|
|
||||||
newLines.push(added)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
oldLines.push(" " + line.slice(1))
|
|
||||||
newLines.push(" " + line.slice(1))
|
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
oldContent: oldLines.join("\n"),
|
oldContent: oldLines.join("\n"),
|
||||||
newContent: newLines.join("\n"),
|
newContent: newLines.join("\n"),
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user