mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-01 15:32:11 +08:00
test(vscode): add tests for toErrorMessage and improve Error: line matching
Search all stderr lines for the first Error: match (not just the last non-empty line) and extract the message after it. Export toErrorMessage for unit testing.
This commit is contained in:
@@ -208,7 +208,11 @@ export class ServerStartupError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
function toErrorMessage(
|
||||
function stripAnsi(str: string): string {
|
||||
return str.replace(/\x1b\[[0-9;]*m/g, "")
|
||||
}
|
||||
|
||||
export function toErrorMessage(
|
||||
error: string,
|
||||
stderrLines: string[],
|
||||
cliPath?: string,
|
||||
@@ -218,7 +222,11 @@ function toErrorMessage(
|
||||
error: string
|
||||
} {
|
||||
let lines = stderrLines.flatMap((line) => line.split("\n"))
|
||||
const userMessage = [...lines].reverse().find((line) => line.trim() !== "") ?? error
|
||||
|
||||
const errorLine = lines.map(stripAnsi).find((line) => /Error:\s+/.test(line))
|
||||
const userMessage = errorLine
|
||||
? errorLine.match(/Error:\s+(.+)/)![1].trim()
|
||||
: stripAnsi([...lines].reverse().find((line) => line.trim() !== "") ?? error).trim()
|
||||
|
||||
lines = [error, ...lines]
|
||||
if (cliPath && cliPath.trim() !== "") {
|
||||
@@ -228,8 +236,8 @@ function toErrorMessage(
|
||||
const detailsText = lines.join("\n").trim()
|
||||
|
||||
return {
|
||||
userMessage: userMessage,
|
||||
userMessage,
|
||||
userDetails: detailsText,
|
||||
error: error,
|
||||
error,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from "bun:test"
|
||||
import { parseServerPort } from "../../src/services/cli-backend/server-utils"
|
||||
import { toErrorMessage } from "../../src/services/cli-backend/server-manager"
|
||||
|
||||
describe("parseServerPort", () => {
|
||||
it("parses port from standard CLI startup message", () => {
|
||||
@@ -44,3 +45,61 @@ describe("parseServerPort", () => {
|
||||
expect(parseServerPort(output)).toBe(3000)
|
||||
})
|
||||
})
|
||||
|
||||
describe("toErrorMessage", () => {
|
||||
it("uses last non-empty stderr line as userMessage when no Error: line", () => {
|
||||
const result = toErrorMessage("startup failed", ["line one", "line two", ""])
|
||||
expect(result.userMessage).toBe("line two")
|
||||
})
|
||||
|
||||
it("extracts message after Error: when present", () => {
|
||||
const result = toErrorMessage("startup failed", ["some noise", "Error: something went wrong"])
|
||||
expect(result.userMessage).toBe("something went wrong")
|
||||
})
|
||||
|
||||
it("strips ANSI codes before matching Error:", () => {
|
||||
const ansiError = "\x1b[91m\x1b[1mError: \x1b[0mConfig file at /path/kilo.json is not valid JSON(C):"
|
||||
const result = toErrorMessage("startup failed", [ansiError])
|
||||
expect(result.userMessage).toBe("Config file at /path/kilo.json is not valid JSON(C):")
|
||||
})
|
||||
|
||||
it("finds Error: line anywhere, not just the last line", () => {
|
||||
const result = toErrorMessage("startup failed", ["Error: the real problem", "subsequent noise", "more noise"])
|
||||
expect(result.userMessage).toBe("the real problem")
|
||||
})
|
||||
|
||||
it("falls back to last non-empty line when no Error: match", () => {
|
||||
const result = toErrorMessage("startup failed", ["", "just some output", ""])
|
||||
expect(result.userMessage).toBe("just some output")
|
||||
})
|
||||
|
||||
it("falls back to error arg when stderr is empty", () => {
|
||||
const result = toErrorMessage("startup failed", [])
|
||||
expect(result.userMessage).toBe("startup failed")
|
||||
})
|
||||
|
||||
it("strips ANSI from fallback last non-empty line", () => {
|
||||
const result = toErrorMessage("startup failed", ["\x1b[31msome colored output\x1b[0m"])
|
||||
expect(result.userMessage).toBe("some colored output")
|
||||
})
|
||||
|
||||
it("includes error arg in userDetails", () => {
|
||||
const result = toErrorMessage("startup failed", ["some output"])
|
||||
expect(result.userDetails).toContain("startup failed")
|
||||
})
|
||||
|
||||
it("includes CLI path in userDetails when provided", () => {
|
||||
const result = toErrorMessage("startup failed", [], "/usr/local/bin/kilo")
|
||||
expect(result.userDetails).toContain("CLI path: /usr/local/bin/kilo")
|
||||
})
|
||||
|
||||
it("does not include CLI path in userDetails when not provided", () => {
|
||||
const result = toErrorMessage("startup failed", [])
|
||||
expect(result.userDetails).not.toContain("CLI path:")
|
||||
})
|
||||
|
||||
it("returns original error string as error field", () => {
|
||||
const result = toErrorMessage("startup failed", ["some output"])
|
||||
expect(result.error).toBe("startup failed")
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user