mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 02:06:43 +00:00
fix(stt-live-audio): cancel ElevenLabs error response body (#110759)
Avoid buffering unbounded provider error streams and cover the resource lifecycle with a deterministic cancellation contract. Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
co-authored by
Peter Steinberger
parent
6646719c05
commit
09c46fb682
@@ -1,5 +1,6 @@
|
||||
// Elevenlabs tests cover tts plugin behavior.
|
||||
import { MAX_AUDIO_BYTES } from "openclaw/plugin-sdk/media-runtime";
|
||||
import { synthesizeElevenLabsLiveSpeech } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { createStreamingErrorResponse } from "../test-support/streaming-error-response.js";
|
||||
import { elevenLabsTTS, elevenLabsTTSStream } from "./tts.js";
|
||||
@@ -326,3 +327,37 @@ describe("elevenlabs tts diagnostics", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("elevenlabs live audio helper error-path body release", () => {
|
||||
const originalFetch = globalThis.fetch;
|
||||
|
||||
afterEach(() => {
|
||||
globalThis.fetch = originalFetch;
|
||||
});
|
||||
|
||||
it("cancels an unread streaming error body when ElevenLabs returns non-2xx", async () => {
|
||||
const cancel = vi.fn();
|
||||
const response = new Response(
|
||||
new ReadableStream<Uint8Array>({
|
||||
start(controller) {
|
||||
controller.enqueue(new Uint8Array([1, 2, 3]));
|
||||
},
|
||||
cancel,
|
||||
}),
|
||||
{ status: 401 },
|
||||
);
|
||||
globalThis.fetch = vi.fn(async () => response) as typeof fetch;
|
||||
|
||||
await expect(
|
||||
synthesizeElevenLabsLiveSpeech({
|
||||
text: "OpenClaw leak check.",
|
||||
apiKey: "x",
|
||||
outputFormat: "mp3_44100_128",
|
||||
timeoutMs: 1_000,
|
||||
}),
|
||||
).rejects.toThrow("ElevenLabs live TTS failed (401)");
|
||||
|
||||
expect(cancel).toHaveBeenCalledOnce();
|
||||
expect(response.bodyUsed).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -71,6 +71,9 @@ export async function synthesizeElevenLabsLiveSpeech(params: {
|
||||
signal: controller.signal,
|
||||
});
|
||||
if (!response.ok) {
|
||||
// Error payloads are not used by the live fixture. Cancel instead of buffering an
|
||||
// untrusted or unbounded body so Undici can release the connection promptly.
|
||||
await response.body?.cancel().catch(() => undefined);
|
||||
throw new Error(`ElevenLabs live TTS failed (${response.status})`);
|
||||
}
|
||||
return Buffer.from(await response.arrayBuffer());
|
||||
|
||||
Reference in New Issue
Block a user