Skip to content

Commit 228a972

Browse files
heavygeeHAPI
andcommitted
fix(voice): wrap startAudioCapture in try/catch to propagate mic errors
An unhandled rejection inside the async onmessage callback does not propagate to the outer startSession Promise — the UI hangs on 'connecting' and the provider socket stays partially open. Wrapping the await in try/catch calls cleanup()/statusCallback('error')/reject() so failures surface correctly. via [HAPI](https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run>
1 parent 44c93b5 commit 228a972

2 files changed

Lines changed: 20 additions & 3 deletions

File tree

web/src/realtime/GeminiLiveVoiceSession.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,17 @@ class GeminiLiveVoiceSessionImpl implements VoiceSession {
177177
setupDone = true
178178
if (DEBUG) console.log('[GeminiLive] Setup complete')
179179

180-
// Await audio capture so setMuted runs after getUserMedia resolves
181-
await startAudioCapture(state.playbackContext!)
180+
// Await audio capture so setMuted runs after getUserMedia resolves.
181+
// Wrap so a mic failure rejects the outer startSession promise.
182+
try {
183+
await startAudioCapture(state.playbackContext!)
184+
} catch (error) {
185+
const message = error instanceof Error ? error.message : 'Microphone error'
186+
cleanup()
187+
state.statusCallback?.('error', message)
188+
reject(error instanceof Error ? error : new Error(message))
189+
return
190+
}
182191
state.statusCallback?.('connected')
183192

184193
const proactive = localStorage.getItem('hapi-voice-proactive') === 'true'

web/src/realtime/QwenVoiceSession.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,15 @@ class QwenVoiceSessionImpl implements VoiceSession {
192192
if (eventType === 'session.updated') {
193193
sessionReady = true
194194
if (DEBUG) console.log('[Qwen] Session configured')
195-
await startAudioCapture(state.playbackContext!)
195+
try {
196+
await startAudioCapture(state.playbackContext!)
197+
} catch (error) {
198+
const message = error instanceof Error ? error.message : 'Microphone error'
199+
cleanup()
200+
state.statusCallback?.('error', message)
201+
reject(error instanceof Error ? error : new Error(message))
202+
return
203+
}
196204
state.statusCallback?.('connected')
197205
resolve()
198206
return

0 commit comments

Comments
 (0)