fix(clawhub): wrap malformed marketplace json

This commit is contained in:
Vincent Koc
2026-05-15 08:02:13 +08:00
parent 77e5a492f2
commit eb07aba973
3 changed files with 19 additions and 1 deletions

View File

@@ -94,6 +94,7 @@ Docs: https://docs.openclaw.ai
- Twilio voice-call: report malformed media stream WebSocket JSON with an owned parser error instead of logging raw parser failures.
- Tlon/Urbit: report malformed SSE event JSON with an owned parser error instead of logging raw parser failures.
- Signal: return a stable installer error when GitHub release metadata is malformed JSON.
- ClawHub: report malformed successful marketplace JSON responses with owned errors instead of leaking raw parser failures.
- Matrix: ignore malformed percent-encoding in optional location URI parameters instead of letting a bad `geo:` event abort inbound message handling.
- Web search: auto-detect Brave through its legacy `tools.web.search.apiKey` compatibility fallback while keeping doctor migration to `plugins.entries.brave.config.webSearch.apiKey` as the canonical repair, so allowlisted isolated cron runs do not report `web_search` unavailable before migration. Fixes #81538. Thanks @atomicmonk.
- Plugins: memoize repeated in-process plugin metadata snapshots and keep vanished managed-install residue from forcing full derived discovery, reducing gateway/status startup scans under large plugin sets. Fixes #81143 and #79806. (#81570) Thanks @Kaspre, @holgergruenhagen, @JanPlessow, and @mjamiv.

View File

@@ -483,6 +483,19 @@ describe("clawhub helpers", () => {
).rejects.toThrow(/Rate limit exceeded Sign in for higher rate limits\.$/);
});
it("wraps malformed successful ClawHub JSON responses", async () => {
await expect(
searchClawHubSkills({
query: "calendar",
fetchImpl: async () =>
new Response("{not json", {
status: 200,
headers: { "content-type": "application/json" },
}),
}),
).rejects.toThrow("ClawHub /api/v1/search returned malformed JSON");
});
it("annotates 429 errors with the reset hint but no sign-in hint when authenticated", async () => {
process.env.OPENCLAW_CLAWHUB_TOKEN = "env-token-123";
await expect(

View File

@@ -634,7 +634,11 @@ async function fetchJson<T>(params: ClawHubRequestParams): Promise<T> {
if (!response.ok) {
throw await buildClawHubError(response, url, hasToken);
}
return (await response.json()) as T;
try {
return (await response.json()) as T;
} catch (cause) {
throw new Error(`ClawHub ${url.pathname} returned malformed JSON`, { cause });
}
}
async function readClawHubResponseBytes(params: {