fix(mobile): route dictation setup errors to setup sheet

This commit is contained in:
Brennan Benson
2026-07-30 21:05:05 -07:00
parent 8fef6db292
commit f91b87411d
2 changed files with 47 additions and 10 deletions
+13 -10
View File
@@ -1195,6 +1195,16 @@ export default function SessionScreen() {
const { toggleTabChatView, showNativeChat, showNativeChatRef } = nativeChatController
nativeChatSendError.bannerMountedRef.current = showNativeChat
function handleDictationError(err: unknown) {
const error = err instanceof Error ? err : new Error(String(err))
if (isDictationSetupRequiredError(error.message)) {
setShowDictationSetup(true)
return
}
triggerError()
showToast(error.message)
}
const dictation = useMobileDictation({
client,
enabled: canSend,
@@ -1236,13 +1246,7 @@ export default function SessionScreen() {
},
onError: (err) => {
dictationRouteContextRef.current = null
// Dictation not set up on desktop → open the setup sheet instead of a dead-end toast.
if (isDictationSetupRequiredError(err.message)) {
setShowDictationSetup(true)
return
}
triggerError()
showToast(err.message)
handleDictationError(err)
}
})
@@ -1255,10 +1259,9 @@ export default function SessionScreen() {
if (dictationRouteContextRef.current === routeContext) {
dictationRouteContextRef.current = null
}
triggerError()
showToast(err instanceof Error ? err.message : String(err))
handleDictationError(err)
})
}, [activeHandle, dictation, liveInputTerminalHandles, triggerError, showToast])
}, [activeHandle, dictation, handleDictationError, liveInputTerminalHandles])
const cancelDictation = useCallback(() => {
dictationRouteContextRef.current = null
@@ -0,0 +1,34 @@
import { readFileSync } from 'node:fs'
import { describe, expect, it } from 'vitest'
const sessionRouteSource = readFileSync(
new URL('../../app/h/[hostId]/session/[worktreeId].tsx', import.meta.url),
'utf8'
)
function routeSlice(anchorStart: string, anchorEnd: string): string {
const start = sessionRouteSource.indexOf(anchorStart)
expect(start).toBeGreaterThanOrEqual(0)
const end = sessionRouteSource.indexOf(anchorEnd, start)
expect(end).toBeGreaterThan(start)
return sessionRouteSource.slice(start, end)
}
describe('mobile dictation error routing', () => {
it('keeps setup tokens out of startup and in-flight error toasts', () => {
const owner = routeSlice(
'function handleDictationError(err: unknown)',
'const dictation = useMobileDictation({'
)
expect(owner).toContain('isDictationSetupRequiredError(error.message)')
expect(owner).toContain('setShowDictationSetup(true)')
const hook = routeSlice('const dictation = useMobileDictation({', 'const startDictation')
expect(hook).toContain('handleDictationError(err)')
const start = routeSlice('const startDictation', 'const cancelDictation')
expect(start).toContain('handleDictationError(err)')
expect(start).not.toContain('showToast(')
expect(sessionRouteSource.match(/handleDictationError\(err\)/g)).toHaveLength(2)
})
})