

























@@ -277,6 +277,54 @@ describe("Google speech provider", () => {
277277expect(result.audioBuffer.subarray(44)).toEqual(pcm);
278278});
279279280+it("retries once when Gemini TTS fetch aborts", async () => {
281+const pcm = Buffer.from([7, 0, 8, 0]);
282+const abortError = new Error("This operation was aborted");
283+abortError.name = "AbortError";
284+const requestSequence = vi
285+.fn()
286+.mockRejectedValueOnce(abortError)
287+.mockResolvedValueOnce({
288+response: googleTtsResponse(pcm),
289+release: vi.fn(async () => {}),
290+});
291+postJsonRequestMock.mockImplementation(requestSequence);
292+const provider = buildGoogleSpeechProvider();
293+294+const result = await provider.synthesize({
295+text: "Retry aborted fetch.",
296+cfg: {},
297+providerConfig: {
298+apiKey: "google-test-key",
299+},
300+target: "audio-file",
301+timeoutMs: 5_000,
302+});
303+304+expect(requestSequence).toHaveBeenCalledTimes(2);
305+expect(result.audioBuffer.subarray(44)).toEqual(pcm);
306+});
307+308+it("does not retry non-transient Gemini TTS request failures", async () => {
309+const requestSequence = vi.fn().mockRejectedValueOnce(new Error("invalid request"));
310+postJsonRequestMock.mockImplementation(requestSequence);
311+const provider = buildGoogleSpeechProvider();
312+313+await expect(
314+provider.synthesize({
315+text: "Do not retry this.",
316+cfg: {},
317+providerConfig: {
318+apiKey: "google-test-key",
319+},
320+target: "audio-file",
321+timeoutMs: 5_000,
322+}),
323+).rejects.toThrow("invalid request");
324+325+expect(requestSequence).toHaveBeenCalledTimes(1);
326+});
327+280328it("falls back to GEMINI_API_KEY and configured Google API base URL", async () => {
281329vi.stubEnv("GEMINI_API_KEY", "env-google-key");
282330const requestMock = installGoogleTtsRequestMock();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。