fix(twilio): wrap malformed api json · openclaw/openclaw@99d7b20
vincentkoc
·
2026-05-14
·
via Recent Commits to openclaw:main
File tree
extensions/voice-call/src/providers/twilio
| Original file line number | Diff line number | Diff line change |
|---|
@@ -49,6 +49,7 @@ Docs: https://docs.openclaw.ai
|
49 | 49 | - Telnyx voice-call: use the raw `client_state` fallback when webhook state is malformed base64 instead of using silently corrupted decoded text. |
50 | 50 | - Google Meet: report malformed node-host params JSON with plugin-owned errors instead of leaking raw JSON parser failures. |
51 | 51 | - CLI/export-trajectory: report malformed encoded request JSON with a stable CLI error instead of leaking raw parser output. |
| 52 | +- Twilio voice-call: report malformed successful API JSON responses with provider-owned errors instead of leaking raw parser failures. |
52 | 53 | - 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. |
53 | 54 | - 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. |
54 | 55 | - 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 |
|---|
@@ -128,6 +128,25 @@ describe("twilioApiRequest", () => {
|
128 | 128 | expect(release).toHaveBeenCalledTimes(1); |
129 | 129 | }); |
130 | 130 | |
| 131 | +it("wraps malformed json success responses with an owned error", async () => { |
| 132 | +const release = vi.fn(async () => {}); |
| 133 | +fetchWithSsrFGuardMock.mockResolvedValue({ |
| 134 | +response: new Response("{not json", { status: 200 }), |
| 135 | + release, |
| 136 | +}); |
| 137 | + |
| 138 | +await expect( |
| 139 | +twilioApiRequest({ |
| 140 | +baseUrl: "https://api.twilio.com", |
| 141 | +accountSid: "AC123", |
| 142 | +authToken: "secret", |
| 143 | +endpoint: "/Calls.json", |
| 144 | +body: {}, |
| 145 | +}), |
| 146 | +).rejects.toThrow("Twilio API returned malformed JSON."); |
| 147 | +expect(release).toHaveBeenCalledTimes(1); |
| 148 | +}); |
| 149 | + |
131 | 150 | it("exposes structured Twilio error codes from json error bodies", async () => { |
132 | 151 | const release = vi.fn(async () => {}); |
133 | 152 | fetchWithSsrFGuardMock.mockResolvedValue({ |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -86,7 +86,14 @@ export async function twilioApiRequest<T = unknown>(params: {
|
86 | 86 | } |
87 | 87 | |
88 | 88 | const text = await response.text(); |
89 | | -return text ? (JSON.parse(text) as T) : (undefined as T); |
| 89 | +if (!text) { |
| 90 | +return undefined as T; |
| 91 | +} |
| 92 | +try { |
| 93 | +return JSON.parse(text) as T; |
| 94 | +} catch { |
| 95 | +throw new Error("Twilio API returned malformed JSON."); |
| 96 | +} |
90 | 97 | } finally { |
91 | 98 | await release(); |
92 | 99 | } |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。