mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-06 08:18:39 +00:00
fix: internationalize hardcoded error messages
- Added new error message keys to English locale files (tools.json and common.json)
- Replaced hardcoded 'Roo tried to use' messages with i18n calls
- Replaced other hardcoded error messages in say('error') calls
- Updated test mocks to handle new i18n keys
- Affected files:
- Task.ts: Lines 1058, 2140
- writeToFileTool.ts: Line 148
- askFollowupQuestionTool.ts: Line 51
- applyDiffTool.ts: Line 86
- searchAndReplaceTool.ts: Lines 140, 159
- insertContentTool.ts: Line 90
- presentAssistantMessage.ts: Line 318
- useMcpToolTool.spec.ts: Test mock update
This change ensures all error messages can be properly translated to the 17+ languages supported by Roo Code.
This commit is contained in:
parent
2e99d5bf1b
commit
b446b1d986
10 changed files with 56 additions and 22 deletions
|
|
@ -35,6 +35,7 @@ import { Task } from "../task/Task"
|
|||
import { codebaseSearchTool } from "../tools/codebaseSearchTool"
|
||||
import { experiments, EXPERIMENT_IDS } from "../../shared/experiments"
|
||||
import { applyDiffToolLegacy } from "../tools/applyDiffTool"
|
||||
import { t } from "../../i18n"
|
||||
|
||||
/**
|
||||
* Processes and presents assistant message content to the user interface.
|
||||
|
|
@ -316,7 +317,10 @@ export async function presentAssistantMessage(cline: Task) {
|
|||
|
||||
await cline.say(
|
||||
"error",
|
||||
`Error ${action}:\n${error.message ?? JSON.stringify(serializeError(error), null, 2)}`,
|
||||
t("tools:errors.toolExecutionError", {
|
||||
action,
|
||||
error: error.message ?? JSON.stringify(serializeError(error), null, 2),
|
||||
}),
|
||||
)
|
||||
|
||||
pushToolResult(formatResponse.toolError(errorString))
|
||||
|
|
|
|||
|
|
@ -1053,12 +1053,17 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
}
|
||||
|
||||
async sayAndCreateMissingParamError(toolName: ToolName, paramName: string, relPath?: string) {
|
||||
await this.say(
|
||||
"error",
|
||||
`Roo tried to use ${toolName}${
|
||||
relPath ? ` for '${relPath.toPosix()}'` : ""
|
||||
} without value for required parameter '${paramName}'. Retrying...`,
|
||||
)
|
||||
const errorMessage = relPath
|
||||
? t("tools:errors.missingRequiredParameter.withPath", {
|
||||
toolName,
|
||||
relPath: relPath.toPosix(),
|
||||
paramName,
|
||||
})
|
||||
: t("tools:errors.missingRequiredParameter.withoutPath", {
|
||||
toolName,
|
||||
paramName,
|
||||
})
|
||||
await this.say("error", errorMessage)
|
||||
return formatResponse.toolError(formatResponse.missingToolParameterError(paramName))
|
||||
}
|
||||
|
||||
|
|
@ -2135,10 +2140,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
// If there's no assistant_responses, that means we got no text
|
||||
// or tool_use content blocks from API which we should assume is
|
||||
// an error.
|
||||
await this.say(
|
||||
"error",
|
||||
"Unexpected API Response: The language model did not provide any assistant messages. This may indicate an issue with the API or the model's output.",
|
||||
)
|
||||
await this.say("error", t("common:errors.unexpectedApiResponse"))
|
||||
|
||||
await this.addToApiConversationHistory({
|
||||
role: "assistant",
|
||||
|
|
|
|||
|
|
@ -15,6 +15,13 @@ vi.mock("../../prompts/responses", () => ({
|
|||
|
||||
vi.mock("../../../i18n", () => ({
|
||||
t: vi.fn((key: string, params?: any) => {
|
||||
// Handle the new tools error messages
|
||||
if (key === "tools:errors.missingRequiredParameter.withPath" && params) {
|
||||
return `Roo tried to use ${params.toolName} for '${params.relPath}' without value for required parameter '${params.paramName}'. Retrying...`
|
||||
}
|
||||
if (key === "tools:errors.missingRequiredParameter.withoutPath" && params) {
|
||||
return `Roo tried to use ${params.toolName} without value for required parameter '${params.paramName}'. Retrying...`
|
||||
}
|
||||
if (key === "mcp:errors.invalidJsonArgument" && params?.toolName) {
|
||||
return `Roo tried to use ${params.toolName} with an invalid JSON argument. Retrying...`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { fileExistsAtPath } from "../../utils/fs"
|
|||
import { RecordSource } from "../context-tracking/FileContextTrackerTypes"
|
||||
import { unescapeHtmlEntities } from "../../utils/text-normalization"
|
||||
import { EXPERIMENT_IDS, experiments } from "../../shared/experiments"
|
||||
import { t } from "../../i18n"
|
||||
|
||||
export async function applyDiffToolLegacy(
|
||||
cline: Task,
|
||||
|
|
@ -82,7 +83,7 @@ export async function applyDiffToolLegacy(
|
|||
if (!fileExists) {
|
||||
cline.consecutiveMistakeCount++
|
||||
cline.recordToolError("apply_diff")
|
||||
const formattedError = `File does not exist at path: ${absolutePath}\n\n<error_details>\nThe specified file could not be found. Please verify the file path and try again.\n</error_details>`
|
||||
const formattedError = t("tools:errors.fileNotFound", { path: absolutePath })
|
||||
await cline.say("error", formattedError)
|
||||
pushToolResult(formattedError)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { Task } from "../task/Task"
|
|||
import { ToolUse, AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "../../shared/tools"
|
||||
import { formatResponse } from "../prompts/responses"
|
||||
import { parseXml } from "../../utils/xml"
|
||||
import { t } from "../../i18n"
|
||||
|
||||
export async function askFollowupQuestionTool(
|
||||
cline: Task,
|
||||
|
|
@ -48,7 +49,7 @@ export async function askFollowupQuestionTool(
|
|||
} catch (error) {
|
||||
cline.consecutiveMistakeCount++
|
||||
cline.recordToolError("ask_followup_question")
|
||||
await cline.say("error", `Failed to parse operations: ${error.message}`)
|
||||
await cline.say("error", t("tools:errors.parseOperationsFailed", { error: error.message }))
|
||||
pushToolResult(formatResponse.toolError("Invalid operations xml format"))
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { fileExistsAtPath } from "../../utils/fs"
|
|||
import { insertGroups } from "../diff/insert-groups"
|
||||
import { DEFAULT_WRITE_DELAY_MS } from "@roo-code/types"
|
||||
import { EXPERIMENT_IDS, experiments } from "../../shared/experiments"
|
||||
import { t } from "../../i18n"
|
||||
|
||||
export async function insertContentTool(
|
||||
cline: Task,
|
||||
|
|
@ -86,7 +87,7 @@ export async function insertContentTool(
|
|||
if (lineNumber > 1) {
|
||||
cline.consecutiveMistakeCount++
|
||||
cline.recordToolError("insert_content")
|
||||
const formattedError = `Cannot insert content at line ${lineNumber} into a non-existent file. For new files, 'line' must be 0 (to append) or 1 (to insert at the beginning).`
|
||||
const formattedError = t("tools:errors.insertContentNewFile", { lineNumber })
|
||||
await cline.say("error", formattedError)
|
||||
pushToolResult(formattedError)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { fileExistsAtPath } from "../../utils/fs"
|
|||
import { RecordSource } from "../context-tracking/FileContextTrackerTypes"
|
||||
import { DEFAULT_WRITE_DELAY_MS } from "@roo-code/types"
|
||||
import { EXPERIMENT_IDS, experiments } from "../../shared/experiments"
|
||||
import { t } from "../../i18n"
|
||||
|
||||
/**
|
||||
* Tool for performing search and replace operations on files
|
||||
|
|
@ -135,7 +136,7 @@ export async function searchAndReplaceTool(
|
|||
cline.consecutiveMistakeCount++
|
||||
cline.recordToolError("search_and_replace")
|
||||
const formattedError = formatResponse.toolError(
|
||||
`File does not exist at path: ${absolutePath}\nThe specified file could not be found. Please verify the file path and try again.`,
|
||||
t("tools:errors.fileNotFoundSimple", { path: absolutePath }),
|
||||
)
|
||||
await cline.say("error", formattedError)
|
||||
pushToolResult(formattedError)
|
||||
|
|
@ -152,9 +153,10 @@ export async function searchAndReplaceTool(
|
|||
} catch (error) {
|
||||
cline.consecutiveMistakeCount++
|
||||
cline.recordToolError("search_and_replace")
|
||||
const errorMessage = `Error reading file: ${absolutePath}\nFailed to read the file content: ${
|
||||
error instanceof Error ? error.message : String(error)
|
||||
}\nPlease verify file permissions and try again.`
|
||||
const errorMessage = t("tools:errors.fileReadError", {
|
||||
path: absolutePath,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
})
|
||||
const formattedError = formatResponse.toolError(errorMessage)
|
||||
await cline.say("error", formattedError)
|
||||
pushToolResult(formattedError)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import { detectCodeOmission } from "../../integrations/editor/detect-omission"
|
|||
import { unescapeHtmlEntities } from "../../utils/text-normalization"
|
||||
import { DEFAULT_WRITE_DELAY_MS } from "@roo-code/types"
|
||||
import { EXPERIMENT_IDS, experiments } from "../../shared/experiments"
|
||||
import { t } from "../../i18n"
|
||||
|
||||
export async function writeToFileTool(
|
||||
cline: Task,
|
||||
|
|
@ -145,9 +146,10 @@ export async function writeToFileTool(
|
|||
// Use more specific error message for line_count that provides guidance based on the situation
|
||||
await cline.say(
|
||||
"error",
|
||||
`Roo tried to use write_to_file${
|
||||
relPath ? ` for '${relPath.toPosix()}'` : ""
|
||||
} but the required parameter 'line_count' was missing or truncated after ${actualLineCount} lines of content were written. Retrying...`,
|
||||
t("tools:errors.lineCountMissing", {
|
||||
relPath: relPath ? ` for '${relPath.toPosix()}'` : "",
|
||||
actualLineCount,
|
||||
}),
|
||||
)
|
||||
|
||||
pushToolResult(
|
||||
|
|
|
|||
|
|
@ -103,7 +103,8 @@
|
|||
},
|
||||
"roo": {
|
||||
"authenticationRequired": "Roo provider requires cloud authentication. Please sign in to Roo Code Cloud."
|
||||
}
|
||||
},
|
||||
"unexpectedApiResponse": "Unexpected API Response: The language model did not provide any assistant messages. This may indicate an issue with the API or the model's output."
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "No terminal content selected",
|
||||
|
|
|
|||
|
|
@ -14,5 +14,18 @@
|
|||
"errors": {
|
||||
"policy_restriction": "Failed to create new task due to policy restrictions."
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"missingRequiredParameter": {
|
||||
"withPath": "Roo tried to use {{toolName}} for '{{relPath}}' without value for required parameter '{{paramName}}'. Retrying...",
|
||||
"withoutPath": "Roo tried to use {{toolName}} without value for required parameter '{{paramName}}'. Retrying..."
|
||||
},
|
||||
"lineCountMissing": "Roo tried to use write_to_file{{relPath}} but the required parameter 'line_count' was missing or truncated after {{actualLineCount}} lines of content were written. Retrying...",
|
||||
"parseOperationsFailed": "Failed to parse operations: {{error}}",
|
||||
"fileNotFound": "File does not exist at path: {{path}}\n\n<error_details>\nThe specified file could not be found. Please verify the file path and try again.\n</error_details>",
|
||||
"fileNotFoundSimple": "File does not exist at path: {{path}}\nThe specified file could not be found. Please verify the file path and try again.",
|
||||
"fileReadError": "Error reading file: {{path}}\nFailed to read the file content: {{error}}\nPlease verify file permissions and try again.",
|
||||
"insertContentNewFile": "Cannot insert content at line {{lineNumber}} into a non-existent file. For new files, 'line' must be 0 (to append) or 1 (to insert at the beginning).",
|
||||
"toolExecutionError": "Error {{action}}:\n{{error}}"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue