Browse Source

add timeout

drawing-pad
Stephanie Gredell 1 month ago
parent
commit
4fae2bb2b2
  1. 22
      backend/src/controllers/speechSounds.controller.ts
  2. 12
      backend/src/services/elevenlabs.service.ts

22
backend/src/controllers/speechSounds.controller.ts

@ -77,8 +77,8 @@ export async function pronounceWord(req: AuthRequest, res: Response) { @@ -77,8 +77,8 @@ export async function pronounceWord(req: AuthRequest, res: Response) {
try {
const { audio, format } = await generateSpeech(wordText, voiceId);
// Store in cache
await db.execute({
// Store in cache (don't await - cache in background to return faster)
db.execute({
sql: `
INSERT INTO word_pronunciations (word_id, voice_id, audio_data, audio_format)
VALUES (?, ?, ?, ?)
@ -88,9 +88,12 @@ export async function pronounceWord(req: AuthRequest, res: Response) { @@ -88,9 +88,12 @@ export async function pronounceWord(req: AuthRequest, res: Response) {
created_at = CURRENT_TIMESTAMP
`,
args: [wordId, voiceId, audio, format]
}).catch(err => {
console.error('Error caching pronunciation:', err);
// Don't fail the request if caching fails
});
// Return audio
// Return audio immediately
const contentType = format === 'mp3' ? 'audio/mpeg' :
format === 'wav' ? 'audio/wav' :
format === 'ogg' ? 'audio/ogg' : 'audio/mpeg';
@ -113,11 +116,22 @@ export async function pronounceWord(req: AuthRequest, res: Response) { @@ -113,11 +116,22 @@ export async function pronounceWord(req: AuthRequest, res: Response) {
});
}
// Handle timeout errors
if (error.message.includes('timed out')) {
return res.status(504).json({
success: false,
error: {
code: 'SPEECH_GENERATION_TIMEOUT',
message: 'Speech generation timed out. Please try again.'
}
});
}
return res.status(500).json({
success: false,
error: {
code: 'SPEECH_GENERATION_ERROR',
message: 'Failed to generate speech pronunciation'
message: error.message || 'Failed to generate speech pronunciation'
}
});
}

12
backend/src/services/elevenlabs.service.ts

@ -27,6 +27,10 @@ export async function generateSpeech( @@ -27,6 +27,10 @@ export async function generateSpeech(
}
try {
// Add timeout to prevent gateway timeouts (30 seconds)
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);
const response = await fetch(`${ELEVENLABS_API_URL}/text-to-speech/${voiceId}`, {
method: 'POST',
headers: {
@ -38,9 +42,12 @@ export async function generateSpeech( @@ -38,9 +42,12 @@ export async function generateSpeech(
text: text.trim(),
model_id: 'eleven_turbo_v2_5'
// No voice_settings - uses the voice's default settings from ElevenLabs
})
}),
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
const errorText = await response.text();
console.error('ElevenLabs API error:', response.status, errorText);
@ -65,6 +72,9 @@ export async function generateSpeech( @@ -65,6 +72,9 @@ export async function generateSpeech(
format
};
} catch (error: any) {
if (error.name === 'AbortError') {
throw new Error('ElevenLabs API request timed out after 30 seconds');
}
if (error.message.includes('ElevenLabs API error')) {
throw error;
}

Loading…
Cancel
Save