mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-18 10:44:45 +00:00
fix(memory): wrap malformed remote json
This commit is contained in:
@@ -92,6 +92,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Tavily: report malformed search and extract API JSON with provider-owned errors instead of leaking raw parser failures.
|
||||
- Perplexity: report malformed Search API and chat completion JSON with provider-owned errors instead of leaking raw parser failures.
|
||||
- Exa: report malformed search API JSON with a provider-owned error instead of leaking raw parser failures.
|
||||
- Memory host SDK: report malformed remote JSON with caller-scoped errors for POST and batch file upload responses instead of leaking raw parser failures.
|
||||
- Twilio voice-call: report malformed successful API JSON responses with provider-owned errors instead of leaking raw parser failures.
|
||||
- Voice-call provider APIs: report malformed successful guarded JSON responses with provider-prefixed errors instead of leaking raw parser failures.
|
||||
- Realtime transcription: report malformed provider websocket JSON frames with owned parser errors instead of leaking raw `SyntaxError` objects.
|
||||
|
||||
41
packages/memory-host-sdk/src/host/batch-upload.test.ts
Normal file
41
packages/memory-host-sdk/src/host/batch-upload.test.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { uploadBatchJsonlFile } from "./batch-upload.js";
|
||||
import { withRemoteHttpResponse } from "./remote-http.js";
|
||||
|
||||
vi.mock("./remote-http.js", () => ({
|
||||
withRemoteHttpResponse: vi.fn(),
|
||||
}));
|
||||
|
||||
const remoteHttpMock = vi.mocked(withRemoteHttpResponse);
|
||||
|
||||
function textResponse(body: string, status: number): Response {
|
||||
return {
|
||||
ok: status >= 200 && status < 300,
|
||||
status,
|
||||
json: async () => JSON.parse(body) as unknown,
|
||||
text: async () => body,
|
||||
} as Response;
|
||||
}
|
||||
|
||||
describe("uploadBatchJsonlFile", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("wraps malformed file-upload JSON with the request error prefix", async () => {
|
||||
remoteHttpMock.mockImplementationOnce(async (params) => {
|
||||
return await params.onResponse(textResponse("{ nope", 200));
|
||||
});
|
||||
|
||||
await expect(
|
||||
uploadBatchJsonlFile({
|
||||
client: {
|
||||
baseUrl: "https://memory.example/v1",
|
||||
headers: { Authorization: "Bearer test" },
|
||||
},
|
||||
requests: [{ input: "one" }],
|
||||
errorPrefix: "file upload failed",
|
||||
}),
|
||||
).rejects.toThrow("file upload failed: malformed JSON response");
|
||||
});
|
||||
});
|
||||
@@ -34,7 +34,11 @@ export async function uploadBatchJsonlFile(params: {
|
||||
const text = await fileRes.text();
|
||||
throw new Error(`${params.errorPrefix}: ${fileRes.status} ${text}`);
|
||||
}
|
||||
return (await fileRes.json()) as { id?: string };
|
||||
try {
|
||||
return (await fileRes.json()) as { id?: string };
|
||||
} catch (cause) {
|
||||
throw new Error(`${params.errorPrefix}: malformed JSON response`, { cause });
|
||||
}
|
||||
},
|
||||
});
|
||||
if (!filePayload.id) {
|
||||
|
||||
@@ -70,4 +70,20 @@ describe("postJson", () => {
|
||||
expect((error as Error).message).toBe("post failed: 502 bad gateway");
|
||||
expect((error as { status?: unknown }).status).toBe(502);
|
||||
});
|
||||
|
||||
it("wraps malformed success JSON with the request error prefix", async () => {
|
||||
remoteHttpMock.mockImplementationOnce(async (params) => {
|
||||
return await params.onResponse(textResponse("{ nope", 200));
|
||||
});
|
||||
|
||||
await expect(
|
||||
postJson({
|
||||
url: "https://memory.example/v1/post",
|
||||
headers: {},
|
||||
body: {},
|
||||
errorPrefix: "post failed",
|
||||
parse: () => ({}),
|
||||
}),
|
||||
).rejects.toThrow("post failed: malformed JSON response");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,7 +31,15 @@ export async function postJson<T>(params: {
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
return await params.parse(await res.json());
|
||||
return await params.parse(await readJsonResponse(res, params.errorPrefix));
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function readJsonResponse(res: Response, errorPrefix: string): Promise<unknown> {
|
||||
try {
|
||||
return await res.json();
|
||||
} catch (cause) {
|
||||
throw new Error(`${errorPrefix}: malformed JSON response`, { cause });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user