






















@@ -3,7 +3,14 @@ import path from "node:path";
33import { setTimeout as sleep } from "node:timers/promises";
44import { afterEach, describe, expect, it, vi } from "vitest";
55import { withTempDir } from "../test-helpers/temp-dir.js";
6-import { createAsyncLock, readJsonFile, writeJsonAtomic, writeTextAtomic } from "./json-files.js";
6+import {
7+JsonFileReadError,
8+createAsyncLock,
9+readDurableJsonFile,
10+readJsonFile,
11+writeJsonAtomic,
12+writeTextAtomic,
13+} from "./json-files.js";
714815const originalPlatformDescriptor = Object.getOwnPropertyDescriptor(process, "platform");
916@@ -45,6 +52,23 @@ describe("json file helpers", () => {
4552});
4653});
475455+it("reads durable json strictly while allowing missing files", async () => {
56+await withTempDir({ prefix: "openclaw-json-files-" }, async (base) => {
57+const validPath = path.join(base, "valid.json");
58+const invalidPath = path.join(base, "invalid.json");
59+const missingPath = path.join(base, "missing.json");
60+await fs.writeFile(validPath, '{"ok":true}', "utf8");
61+await fs.writeFile(invalidPath, "{not-json}", "utf8");
62+63+await expect(readDurableJsonFile(validPath)).resolves.toEqual({ ok: true });
64+await expect(readDurableJsonFile(missingPath)).resolves.toBeNull();
65+await expect(readDurableJsonFile(invalidPath)).rejects.toMatchObject({
66+filePath: invalidPath,
67+reason: "parse",
68+} satisfies Partial<JsonFileReadError>);
69+});
70+});
71+4872it("writes json atomically with pretty formatting and optional trailing newline", async () => {
4973await withTempDir({ prefix: "openclaw-json-files-" }, async (base) => {
5074const filePath = path.join(base, "nested", "config.json");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。