mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:40:44 +00:00
fix: format acpx doctor details safely
This commit is contained in:
@@ -276,6 +276,32 @@ describe("createAcpxRuntimeService", () => {
|
||||
await service.stop?.(ctx);
|
||||
});
|
||||
|
||||
it("formats non-string doctor details without losing object payloads", async () => {
|
||||
const workspaceDir = await makeTempDir();
|
||||
const ctx = createServiceContext(workspaceDir);
|
||||
const runtime = createMockRuntime({
|
||||
doctor: async () => ({
|
||||
ok: false,
|
||||
message: "probe failed",
|
||||
details: [{ code: "ACP_CLOSED", agent: "codex" }, new Error("stdin closed")],
|
||||
}),
|
||||
isHealthy: () => false,
|
||||
});
|
||||
const service = createAcpxRuntimeService({
|
||||
runtimeFactory: () => runtime as never,
|
||||
});
|
||||
|
||||
await service.start(ctx);
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(ctx.logger.warn).toHaveBeenCalledWith(
|
||||
'embedded acpx runtime backend probe failed: probe failed ({"code":"ACP_CLOSED","agent":"codex"}; stdin closed)',
|
||||
);
|
||||
});
|
||||
|
||||
await service.stop?.(ctx);
|
||||
});
|
||||
|
||||
it("can skip the embedded runtime backend via env", async () => {
|
||||
process.env.OPENCLAW_SKIP_ACPX_RUNTIME = "1";
|
||||
const workspaceDir = await makeTempDir();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import fs from "node:fs/promises";
|
||||
import { inspect } from "node:util";
|
||||
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
||||
import type {
|
||||
AcpRuntime,
|
||||
@@ -79,8 +80,36 @@ function warnOnIgnoredLegacyCompatibilityConfig(params: {
|
||||
);
|
||||
}
|
||||
|
||||
function formatDoctorFailureMessage(report: { message: string; details?: string[] }): string {
|
||||
const detailText = report.details?.filter(Boolean).join("; ").trim();
|
||||
function formatDoctorDetail(detail: unknown): string | null {
|
||||
if (!detail) {
|
||||
return null;
|
||||
}
|
||||
if (typeof detail === "string") {
|
||||
return detail.trim() || null;
|
||||
}
|
||||
if (detail instanceof Error) {
|
||||
return formatErrorMessage(detail);
|
||||
}
|
||||
if (typeof detail === "object") {
|
||||
try {
|
||||
return JSON.stringify(detail) ?? inspect(detail, { breakLength: Infinity, depth: 3 });
|
||||
} catch {
|
||||
return inspect(detail, { breakLength: Infinity, depth: 3 });
|
||||
}
|
||||
}
|
||||
if (
|
||||
typeof detail === "number" ||
|
||||
typeof detail === "boolean" ||
|
||||
typeof detail === "bigint" ||
|
||||
typeof detail === "symbol"
|
||||
) {
|
||||
return detail.toString();
|
||||
}
|
||||
return inspect(detail, { breakLength: Infinity, depth: 3 });
|
||||
}
|
||||
|
||||
function formatDoctorFailureMessage(report: { message: string; details?: unknown[] }): string {
|
||||
const detailText = report.details?.map(formatDoctorDetail).filter(Boolean).join("; ").trim();
|
||||
return detailText ? `${report.message} (${detailText})` : report.message;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user