Skip to content

Commit 32f1715

Browse files
liangweifengclaude
andcommitted
fix: add 30s timeout to STT batch transcription methods
Browser vs Electron mode consistency audit found: LLM call() had AbortController timeout but both STT batch methods (DashScope and OpenAI-compatible) had none. If STT API hangs, the request would block indefinitely. Added 30s AbortController timeout to both transcribeDashScopeBatch and transcribeOpenAIBatch, matching LLM and browser-side behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 01cc47e commit 32f1715

1 file changed

Lines changed: 30 additions & 10 deletions

File tree

electron/stt-service.ts

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -526,11 +526,21 @@ export class STTService {
526526
body.extra_body = { asr_options: { language: options.language } };
527527
}
528528

529-
const res = await fetch(url, {
530-
method: 'POST',
531-
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` },
532-
body: JSON.stringify(body),
533-
});
529+
const controller = new AbortController();
530+
const timeout = setTimeout(() => controller.abort(), 30_000);
531+
let res: Response;
532+
try {
533+
res = await fetch(url, {
534+
method: 'POST',
535+
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` },
536+
body: JSON.stringify(body),
537+
signal: controller.signal,
538+
});
539+
} catch (e: any) {
540+
clearTimeout(timeout);
541+
throw new Error(e.name === 'AbortError' ? 'DashScope STT request timed out (30s)' : e.message);
542+
}
543+
clearTimeout(timeout);
534544

535545
if (!res.ok) {
536546
throw new Error(`DashScope STT ${parseApiError(res.status, await res.text().catch(() => ''))}`);
@@ -558,11 +568,21 @@ export class STTService {
558568
const url = `${baseUrl}/audio/transcriptions`;
559569
console.log(`[STT] ${provider}${url} model=${model}`);
560570

561-
const res = await fetch(url, {
562-
method: 'POST',
563-
headers: { Authorization: `Bearer ${apiKey}` },
564-
body: formData,
565-
});
571+
const controller = new AbortController();
572+
const timeout = setTimeout(() => controller.abort(), 30_000);
573+
let res: Response;
574+
try {
575+
res = await fetch(url, {
576+
method: 'POST',
577+
headers: { Authorization: `Bearer ${apiKey}` },
578+
body: formData,
579+
signal: controller.signal,
580+
});
581+
} catch (e: any) {
582+
clearTimeout(timeout);
583+
throw new Error(e.name === 'AbortError' ? 'STT request timed out (30s)' : e.message);
584+
}
585+
clearTimeout(timeout);
566586

567587
if (!res.ok) {
568588
throw new Error(`STT ${parseApiError(res.status, await res.text().catch(() => ''))}`);

0 commit comments

Comments
 (0)