Skip to content

Commit ae267db

Browse files
authored
fix(control-ui-assets): preserve diagnostic length cap
1 parent 8b253d4 commit ae267db

2 files changed

Lines changed: 42 additions & 1 deletion

File tree

src/infra/control-ui-assets.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ type FakeFsEntry = { kind: "file"; content: string } | { kind: "dir" };
88
const state = vi.hoisted(() => ({
99
entries: new Map<string, FakeFsEntry>(),
1010
realpaths: new Map<string, string>(),
11+
runCommandWithTimeout: vi.fn(),
1112
}));
1213

1314
const abs = (p: string) => path.resolve(p);
@@ -69,7 +70,11 @@ vi.mock("./openclaw-root.js", () => ({
6970
resolveOpenClawPackageRoot: vi.fn(async () => null),
7071
resolveOpenClawPackageRootSync: vi.fn(() => null),
7172
}));
73+
vi.mock("../process/exec.js", () => ({
74+
runCommandWithTimeout: state.runCommandWithTimeout,
75+
}));
7276

77+
let ensureControlUiAssetsBuilt: typeof import("./control-ui-assets.js").ensureControlUiAssetsBuilt;
7378
let resolveControlUiRepoRoot: typeof import("./control-ui-assets.js").resolveControlUiRepoRoot;
7479
let resolveControlUiDistIndexPath: typeof import("./control-ui-assets.js").resolveControlUiDistIndexPath;
7580
let resolveControlUiDistIndexHealth: typeof import("./control-ui-assets.js").resolveControlUiDistIndexHealth;
@@ -81,6 +86,7 @@ let openclawRoot: typeof import("./openclaw-root.js");
8186
describe("control UI assets helpers (fs-mocked)", () => {
8287
beforeAll(async () => {
8388
({
89+
ensureControlUiAssetsBuilt,
8490
resolveControlUiRepoRoot,
8591
resolveControlUiDistIndexPath,
8692
resolveControlUiDistIndexHealth,
@@ -94,6 +100,7 @@ describe("control UI assets helpers (fs-mocked)", () => {
94100
beforeEach(() => {
95101
state.entries.clear();
96102
state.realpaths.clear();
103+
state.runCommandWithTimeout.mockReset();
97104
vi.clearAllMocks();
98105
});
99106

@@ -179,6 +186,39 @@ describe("control UI assets helpers (fs-mocked)", () => {
179186
});
180187
});
181188

189+
it("keeps a truncated build failure diagnostic within its UTF-16 limit", async () => {
190+
const root = abs("fixtures/build-failure");
191+
const argv1 = path.join(root, "src", "index.ts");
192+
const originalArgv1 = process.argv[1];
193+
setFile(path.join(root, "ui", "vite.config.ts"), "export {};\n");
194+
setFile(path.join(root, "scripts", "ui.js"), "");
195+
state.runCommandWithTimeout.mockResolvedValueOnce({
196+
stdout: "",
197+
stderr: `${"y".repeat(238)}🚀xx`,
198+
code: 1,
199+
signal: null,
200+
killed: false,
201+
termination: "exit",
202+
});
203+
process.argv[1] = argv1;
204+
205+
try {
206+
const result = await ensureControlUiAssetsBuilt({
207+
log: vi.fn(),
208+
error: vi.fn(),
209+
exit: vi.fn(),
210+
});
211+
212+
expect(result).toEqual({
213+
ok: false,
214+
built: false,
215+
message: `Control UI build failed: ${"y".repeat(238)}…`,
216+
});
217+
} finally {
218+
process.argv[1] = originalArgv1;
219+
}
220+
});
221+
182222
it("resolves control-ui root from override file or directory", () => {
183223
const root = abs("fixtures/override");
184224
const uiDir = path.join(root, "dist", "control-ui");

src/infra/control-ui-assets.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import path from "node:path";
33
import { fileURLToPath } from "node:url";
44
import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization";
5+
import { truncateUtf16Safe } from "@openclaw/normalization-core/utf16-slice";
56
import { runCommandWithTimeout } from "../process/exec.js";
67
import { defaultRuntime, type RuntimeEnv } from "../runtime.js";
78
import * as controlUiFsRuntime from "./control-ui-assets.fs.runtime.js";
@@ -285,7 +286,7 @@ function summarizeCommandOutput(text: string): string | undefined {
285286
if (!last) {
286287
return undefined;
287288
}
288-
return last.length > 240 ? `${Array.from(last).slice(0, 239).join("")}…` : last;
289+
return last.length > 240 ? `${truncateUtf16Safe(last, 239)}…` : last;
289290
}
290291

291292
export async function ensureControlUiAssetsBuilt(

0 commit comments

Comments
 (0)