mirror of https://github.com/openclaw/openclaw.git
fix: validate edge tts output file is non-empty before reporting success (#43385) thanks @Huntterxx
Merged after review.\n\nSmall, scoped fix: treat 0-byte Edge TTS output as failure so provider fallback can continue.
This commit is contained in:
parent
c57b750be4
commit
946c24d674
|
|
@ -0,0 +1,69 @@
|
|||
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
let mockTtsPromise = vi.fn<(text: string, filePath: string) => Promise<void>>();
|
||||
|
||||
vi.mock("node-edge-tts", () => ({
|
||||
EdgeTTS: class {
|
||||
ttsPromise(text: string, filePath: string) {
|
||||
return mockTtsPromise(text, filePath);
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
const { edgeTTS } = await import("./tts-core.js");
|
||||
|
||||
const baseEdgeConfig = {
|
||||
enabled: true,
|
||||
voice: "en-US-MichelleNeural",
|
||||
lang: "en-US",
|
||||
outputFormat: "audio-24khz-48kbitrate-mono-mp3",
|
||||
outputFormatConfigured: false,
|
||||
saveSubtitles: false,
|
||||
};
|
||||
|
||||
describe("edgeTTS – empty audio validation", () => {
|
||||
let tempDir: string;
|
||||
|
||||
afterEach(() => {
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it("throws when the output file is 0 bytes", async () => {
|
||||
tempDir = mkdtempSync(path.join(tmpdir(), "tts-test-"));
|
||||
const outputPath = path.join(tempDir, "voice.mp3");
|
||||
|
||||
mockTtsPromise = vi.fn(async (_text: string, filePath: string) => {
|
||||
writeFileSync(filePath, "");
|
||||
});
|
||||
|
||||
await expect(
|
||||
edgeTTS({
|
||||
text: "Hello",
|
||||
outputPath,
|
||||
config: baseEdgeConfig,
|
||||
timeoutMs: 10000,
|
||||
}),
|
||||
).rejects.toThrow("Edge TTS produced empty audio file");
|
||||
});
|
||||
|
||||
it("succeeds when the output file has content", async () => {
|
||||
tempDir = mkdtempSync(path.join(tmpdir(), "tts-test-"));
|
||||
const outputPath = path.join(tempDir, "voice.mp3");
|
||||
|
||||
mockTtsPromise = vi.fn(async (_text: string, filePath: string) => {
|
||||
writeFileSync(filePath, Buffer.from([0xff, 0xfb, 0x90, 0x00]));
|
||||
});
|
||||
|
||||
await expect(
|
||||
edgeTTS({
|
||||
text: "Hello",
|
||||
outputPath,
|
||||
config: baseEdgeConfig,
|
||||
timeoutMs: 10000,
|
||||
}),
|
||||
).resolves.toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { rmSync } from "node:fs";
|
||||
import { rmSync, statSync } from "node:fs";
|
||||
import { completeSimple, type TextContent } from "@mariozechner/pi-ai";
|
||||
import { EdgeTTS } from "node-edge-tts";
|
||||
import { ensureCustomApiRegistered } from "../agents/custom-api-registry.js";
|
||||
|
|
@ -715,4 +715,10 @@ export async function edgeTTS(params: {
|
|||
timeout: config.timeoutMs ?? timeoutMs,
|
||||
});
|
||||
await tts.ttsPromise(text, outputPath);
|
||||
|
||||
const { size } = statSync(outputPath);
|
||||
|
||||
if (size === 0) {
|
||||
throw new Error("Edge TTS produced empty audio file");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue