惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
云风的 BLOG
云风的 BLOG
小众软件
小众软件
IT之家
IT之家
T
Tailwind CSS Blog
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
美团技术团队
博客园 - 叶小钗
V
V2EX
博客园 - Franky
大猫的无限游戏
大猫的无限游戏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
阮一峰的网络日志
阮一峰的网络日志
博客园 - 【当耐特】
罗磊的独立博客
博客园_首页
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
爱范儿
爱范儿
宝玉的分享
宝玉的分享
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Jina AI
Jina AI
月光博客
月光博客
有赞技术团队
有赞技术团队

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
fix(sms): bound twilio api response bodies · openclaw/ope...
vincentkoc · 2026-06-19 · via Recent Commits to openclaw:main

@@ -53,6 +53,28 @@ function readUrlEncodedRequestBody(init: RequestInit | undefined): URLSearchPara

5353

throw new Error("Expected Twilio request body to be URL-encoded.");

5454

}

555556+

function cancelTrackedTextResponse(

57+

text: string,

58+

init?: ResponseInit,

59+

): {

60+

response: Response;

61+

wasCanceled: () => boolean;

62+

} {

63+

let canceled = false;

64+

const stream = new ReadableStream<Uint8Array>({

65+

start(controller) {

66+

controller.enqueue(new TextEncoder().encode(text));

67+

},

68+

cancel() {

69+

canceled = true;

70+

},

71+

});

72+

return {

73+

response: new Response(stream, init),

74+

wasCanceled: () => canceled,

75+

};

76+

}

77+5678

describe("Twilio SMS helpers", () => {

5779

afterEach(() => {

5880

fetchWithSsrFGuardMock.mockReset();

@@ -472,6 +494,35 @@ describe("Twilio SMS helpers", () => {

472494

expect(release).toHaveBeenCalledTimes(1);

473495

});

474496497+

it("bounds and cancels oversized guarded Twilio error bodies", async () => {

498+

const release = vi.fn(async () => {});

499+

const tracked = cancelTrackedTextResponse(`${"upstream unavailable ".repeat(512)}tail`, {

500+

status: 503,

501+

});

502+

fetchWithSsrFGuardMock.mockResolvedValue({

503+

response: tracked.response,

504+

release,

505+

});

506+507+

let caught: Error | undefined;

508+

try {

509+

await sendSmsViaTwilio({

510+

account: createAccount(),

511+

to: "+15551234567",

512+

text: "hello",

513+

});

514+

} catch (error) {

515+

caught = error as Error;

516+

}

517+518+

expect(caught?.message).toContain("Twilio SMS send failed (503): upstream unavailable");

519+

expect(caught?.message).toContain("... [truncated]");

520+

expect(caught?.message).not.toContain("tail");

521+

expect(caught?.message.length).toBeLessThan(8_300);

522+

expect(tracked.wasCanceled()).toBe(true);

523+

expect(release).toHaveBeenCalledTimes(1);

524+

});

525+475526

it("rejects malformed JSON from successful Twilio sends", async () => {

476527

const fetchImpl = vi.fn<typeof fetch>(async () => new Response("not json", { status: 201 }));

477528

@@ -503,6 +554,28 @@ describe("Twilio SMS helpers", () => {

503554

expect(release).toHaveBeenCalledTimes(1);

504555

});

505556557+

it("bounds and cancels oversized guarded Twilio success bodies", async () => {

558+

const release = vi.fn(async () => {});

559+

const tracked = cancelTrackedTextResponse("x".repeat(1024 * 1024 + 1), { status: 201 });

560+

fetchWithSsrFGuardMock.mockResolvedValue({

561+

response: tracked.response,

562+

release,

563+

});

564+565+

await expect(

566+

sendSmsViaTwilio({

567+

account: createAccount(),

568+

to: "+15551234567",

569+

text: "hello",

570+

}),

571+

).rejects.toThrow(

572+

"Twilio SMS API response body too large: 1048577 bytes (limit: 1048576 bytes)",

573+

);

574+575+

expect(tracked.wasCanceled()).toBe(true);

576+

expect(release).toHaveBeenCalledTimes(1);

577+

});

578+506579

it("exposes a typed Twilio SMS API error", () => {

507580

const error = new TwilioSmsApiError(

508581

429,