Skip to content

Commit e270192

Browse files
committed
refactor: implement proper typed message for file not found errors
- Add file_not_found_error to clineSays array in message types - Emit typed file_not_found_error message from readFileTool instead of embedding in XML - Handle file_not_found_error in ChatRow switch statement - Remove fragile XML parsing logic for file not found errors - Maintain consistent error handling pattern with other tool errors like diff_error
1 parent 287c8eb commit e270192

File tree

3 files changed

+50
-30
lines changed

3 files changed

+50
-30
lines changed

packages/types/src/message.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ export function isInteractiveAsk(ask: ClineAsk): ask is InteractiveAsk {
134134
* - `checkpoint_saved`: Indicates a checkpoint has been saved
135135
* - `rooignore_error`: Error related to .rooignore file processing
136136
* - `diff_error`: Error occurred while applying a diff/patch
137+
* - `file_not_found_error`: Error when attempting to read a file that doesn't exist
137138
* - `condense_context`: Context condensation/summarization has started
138139
* - `condense_context_error`: Error occurred during context condensation
139140
* - `codebase_search_result`: Results from searching the codebase
@@ -160,6 +161,7 @@ export const clineSays = [
160161
"checkpoint_saved",
161162
"rooignore_error",
162163
"diff_error",
164+
"file_not_found_error",
163165
"condense_context",
164166
"condense_context_error",
165167
"codebase_search_result",

src/core/tools/readFileTool.ts

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -611,18 +611,30 @@ export async function readFileTool(
611611
})
612612
} catch (error) {
613613
let errorMsg = error instanceof Error ? error.message : String(error)
614-
let userFriendlyError = errorMsg
615614

616615
// Check if this is a file not found error
617616
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
618-
userFriendlyError = `File not found: The requested file does not exist in the current workspace.`
619-
}
617+
// Emit a proper typed message for file not found errors
618+
await cline.say(
619+
"file_not_found_error",
620+
JSON.stringify({
621+
filePath: relPath,
622+
error: "The requested file does not exist in the current workspace.",
623+
}),
624+
)
620625

621-
updateFileResult(relPath, {
622-
status: "error",
623-
error: userFriendlyError,
624-
xmlContent: `<file><path>${relPath}</path><error>${userFriendlyError}</error></file>`,
625-
})
626+
updateFileResult(relPath, {
627+
status: "error",
628+
error: "File not found",
629+
xmlContent: `<file><path>${relPath}</path><error>File not found: The requested file does not exist in the current workspace.</error></file>`,
630+
})
631+
} else {
632+
updateFileResult(relPath, {
633+
status: "error",
634+
error: errorMsg,
635+
xmlContent: `<file><path>${relPath}</path><error>${errorMsg}</error></file>`,
636+
})
637+
}
626638
await handleError(`reading file ${relPath}`, error instanceof Error ? error : new Error(errorMsg))
627639
}
628640
}
@@ -702,20 +714,35 @@ export async function readFileTool(
702714
// Handle all errors using per-file format for consistency
703715
const relPath = fileEntries[0]?.path || "unknown"
704716
let errorMsg = error instanceof Error ? error.message : String(error)
705-
let userFriendlyError = errorMsg
706717

707718
// Check if this is a file not found error
708719
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
709-
userFriendlyError = `File not found: The requested file does not exist in the current workspace.`
710-
}
720+
// Emit a proper typed message for file not found errors
721+
await cline.say(
722+
"file_not_found_error",
723+
JSON.stringify({
724+
filePath: relPath,
725+
error: "The requested file does not exist in the current workspace.",
726+
}),
727+
)
711728

712-
// If we have file results, update the first one with the error
713-
if (fileResults.length > 0) {
714-
updateFileResult(relPath, {
715-
status: "error",
716-
error: userFriendlyError,
717-
xmlContent: `<file><path>${relPath}</path><error>${userFriendlyError}</error></file>`,
718-
})
729+
// If we have file results, update the first one with the error
730+
if (fileResults.length > 0) {
731+
updateFileResult(relPath, {
732+
status: "error",
733+
error: "File not found",
734+
xmlContent: `<file><path>${relPath}</path><error>File not found: The requested file does not exist in the current workspace.</error></file>`,
735+
})
736+
}
737+
} else {
738+
// If we have file results, update the first one with the error
739+
if (fileResults.length > 0) {
740+
updateFileResult(relPath, {
741+
status: "error",
742+
error: errorMsg,
743+
xmlContent: `<file><path>${relPath}</path><error>${errorMsg}</error></file>`,
744+
})
745+
}
719746
}
720747

721748
await handleError(`reading file ${relPath}`, error instanceof Error ? error : new Error(errorMsg))

webview-ui/src/components/chat/ChatRow.tsx

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,23 +1054,14 @@ export const ChatRowContent = ({
10541054
case "api_req_finished":
10551055
return null // we should never see this message type
10561056
case "text":
1057-
// Check if this is a file not found error from read_file tool
1058-
if (message.text && message.text.includes("<files>") && message.text.includes("<error>")) {
1059-
// Parse the XML to extract file path and error message
1060-
const fileMatch = message.text.match(
1061-
/<file><path>([^<]+)<\/path><error>([^<]+)<\/error><\/file>/,
1062-
)
1063-
if (fileMatch && fileMatch[2].includes("File not found:")) {
1064-
const filePath = fileMatch[1]
1065-
return <FileNotFoundError filePath={filePath} />
1066-
}
1067-
}
1068-
10691057
return (
10701058
<div>
10711059
<Markdown markdown={message.text} partial={message.partial} />
10721060
</div>
10731061
)
1062+
case "file_not_found_error":
1063+
const errorData = safeJsonParse<{ filePath: string; error: string }>(message.text || "{}")
1064+
return <FileNotFoundError filePath={errorData?.filePath || ""} />
10741065
case "user_feedback":
10751066
return (
10761067
<div className="bg-vscode-editor-background border rounded-xs p-1 overflow-hidden whitespace-pre-wrap">

0 commit comments

Comments
 (0)