fix(qqbot): wrap malformed token json · openclaw/openclaw@d9c6036
vincentkoc
·
2026-05-14
·
via Recent Commits to openclaw:main
File tree
extensions/qqbot/src/engine/api
| Original file line number | Diff line number | Diff line change |
|---|
@@ -61,6 +61,7 @@ Docs: https://docs.openclaw.ai
|
61 | 61 | - Google provider: report malformed SSE stream JSON with provider-owned errors instead of leaking raw parser failures. |
62 | 62 | - Node host: report malformed built-in invoke `paramsJSON` with stable invalid-request errors instead of leaking raw parser failures. |
63 | 63 | - Amazon Bedrock embeddings: report malformed provider response JSON with provider-owned errors instead of leaking raw parser failures. |
| 64 | +- QQBot: report malformed access-token JSON with provider-owned errors instead of leaking raw parser failures. |
64 | 65 | - Models config/auth: stop inferring provider env-var markers from broad `^[A-Z_][A-Z0-9_]*$` strings, and resolve config-backed provider `apiKey` values only through structured env SecretRefs (`secrets.providers[id]` / `secrets.defaults`), so unrelated env vars cannot accidentally become provider credentials. Thanks @sallyom. |
65 | 66 | - Media fetch: skip allocating and buffering the response body for bodyless media responses (HEAD probes and 204-style empty bodies), avoiding wasted heap on streams that carry no payload. Thanks @shakkernerd. |
66 | 67 | - CLI/onboarding: forward provider-specific auth flags (e.g. `--openai-api-key`) through the onboarding wizard so they reach provider auth methods via `ctx.opts`, letting `--openai-api-key "$OPENAI_API_KEY"` skip the redundant "use existing env var?" prompt in non-interactive harnesses. (#81669) Thanks @sjf. |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import { afterEach, describe, expect, it, vi } from "vitest"; |
| 2 | +import { TokenManager } from "./token.js"; |
| 3 | + |
| 4 | +describe("QQBot token manager", () => { |
| 5 | +afterEach(() => { |
| 6 | +vi.unstubAllGlobals(); |
| 7 | +}); |
| 8 | + |
| 9 | +it("wraps malformed access token JSON", async () => { |
| 10 | +vi.stubGlobal( |
| 11 | +"fetch", |
| 12 | +vi.fn().mockResolvedValue( |
| 13 | +new Response("{not json", { |
| 14 | +status: 200, |
| 15 | +headers: { "content-type": "application/json" }, |
| 16 | +}), |
| 17 | +), |
| 18 | +); |
| 19 | + |
| 20 | +await expect(new TokenManager().getAccessToken("app-id", "secret")).rejects.toThrow( |
| 21 | +"QQBot access_token response was malformed JSON", |
| 22 | +); |
| 23 | +}); |
| 24 | +}); |
| Original file line number | Diff line number | Diff line change |
|---|
@@ -228,17 +228,23 @@ export class TokenManager {
|
228 | 228 | `[qqbot:token:${appId}] <<< ${response.status}${traceId ? ` | TraceId: ${traceId}` : ""}`, |
229 | 229 | ); |
230 | 230 | |
231 | | -let data: { access_token?: string; expires_in?: number }; |
| 231 | +let rawBody: string; |
232 | 232 | try { |
233 | | -const rawBody = await response.text(); |
234 | | -const logBody = rawBody.replace(/"access_token"\s*:\s*"[^"]+"/g, '"access_token": "***"'); |
235 | | -this.logger?.debug?.(`[qqbot:token:${appId}] <<< Body: ${logBody}`); |
236 | | -data = JSON.parse(rawBody); |
| 233 | +rawBody = await response.text(); |
237 | 234 | } catch (err) { |
238 | | -throw new Error(`Failed to parse access_token response: ${formatErrorMessage(err)}`, { |
| 235 | +throw new Error(`Failed to read access_token response: ${formatErrorMessage(err)}`, { |
239 | 236 | cause: err, |
240 | 237 | }); |
241 | 238 | } |
| 239 | +const logBody = rawBody.replace(/"access_token"\s*:\s*"[^"]+"/g, '"access_token": "***"'); |
| 240 | +this.logger?.debug?.(`[qqbot:token:${appId}] <<< Body: ${logBody}`); |
| 241 | + |
| 242 | +let data: { access_token?: string; expires_in?: number }; |
| 243 | +try { |
| 244 | +data = JSON.parse(rawBody); |
| 245 | +} catch { |
| 246 | +throw new Error("QQBot access_token response was malformed JSON"); |
| 247 | +} |
242 | 248 | |
243 | 249 | if (!data.access_token) { |
244 | 250 | throw new Error(`Failed to get access_token: ${JSON.stringify(data)}`); |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。