Skip to Content
ExamplesError Recovery

Error Recovery Example

Handle all error cases gracefully with user-friendly messaging and recovery options.

Complete Example

components/RobustVoiceUI.tsx
'use client' import { useState, useEffect, useCallback } from 'react' import { VoiceSessionProvider, useVoiceSession, useConnectionState, useNetworkStatus, VoiceAgentError, VoiceAgentErrorCode } from '@vocobase/voice-client-sdk' export function RobustVoiceUI({ apiKey, agentName }: { apiKey: string; agentName: string }) { return ( <VoiceSessionProvider apiKey={apiKey} agentName={agentName} maxReconnectAttempts={5}> <VoiceInterface /> </VoiceSessionProvider> ) } function VoiceInterface() { const { connect, disconnect, error } = useVoiceSession() const { isConnected, isConnecting, isReconnecting } = useConnectionState() const { isOnline } = useNetworkStatus() const [retryCount, setRetryCount] = useState(0) useEffect(() => { if (isConnected) setRetryCount(0) }, [isConnected]) const isRetryableError = (code: VoiceAgentErrorCode) => { return ['NETWORK_ERROR', 'CONNECTION_FAILED', 'CONCURRENCY_LIMIT'].includes(code) } // Offline state if (!isOnline) { return <OfflineState /> } // Reconnecting state if (isReconnecting) { return <ReconnectingState /> } // Error state if (error) { return ( <ErrorState error={error} retryCount={retryCount} onRetry={() => { setRetryCount(prev => prev + 1) connect() }} canRetry={isRetryableError(error.code)} /> ) } // Normal state return isConnected ? ( <ConnectedState onDisconnect={disconnect} /> ) : ( <IdleState onConnect={connect} isConnecting={isConnecting} /> ) } function ErrorState({ error, retryCount, onRetry, canRetry }) { const configs = { MIC_PERMISSION_DENIED: { icon: '🎤', title: 'Microphone Access Blocked', message: 'We need microphone access to enable voice calls.', action: { label: 'Refresh Page', onClick: () => window.location.reload() } }, INSUFFICIENT_CREDITS: { icon: '💳', title: 'Out of Credits', message: 'Your account needs more credits.', action: { label: 'Purchase Credits', href: 'https://dashboard.vocobase.com/billing' } }, CONCURRENCY_LIMIT: { icon: '📞', title: 'All Lines Busy', message: 'Maximum concurrent calls reached.', action: canRetry ? { label: 'Try Again', onClick: onRetry } : null }, NETWORK_ERROR: { icon: '🌐', title: 'Network Error', message: 'Could not reach our servers.', action: canRetry ? { label: `Retry (${3 - retryCount} left)`, onClick: onRetry } : null }, CONNECTION_FAILED: { icon: '🔌', title: 'Connection Failed', message: 'Could not establish a voice connection.', action: canRetry ? { label: 'Try Again', onClick: onRetry } : null } } const config = configs[error.code] || { icon: '❌', title: 'Error', message: error.message, action: { label: 'Try Again', onClick: onRetry } } return ( <div className="error-state"> <div className="icon">{config.icon}</div> <h3>{config.title}</h3> <p>{config.message}</p> {config.action && ( config.action.href ? ( <a href={config.action.href}>{config.action.label}</a> ) : ( <button onClick={config.action.onClick}>{config.action.label}</button> ) )} </div> ) } function OfflineState() { return ( <div className="state-card"> <div>📡</div> <h3>No Internet Connection</h3> <p>Voice calls require an active internet connection.</p> </div> ) } function ReconnectingState() { return ( <div className="state-card"> <h3>Connection Lost</h3> <p>Attempting to reconnect...</p> </div> ) } function ConnectedState({ onDisconnect }) { return ( <div className="state-card"> <h3>Connected</h3> <button onClick={onDisconnect}>End Call</button> </div> ) } function IdleState({ onConnect, isConnecting }) { return ( <div className="state-card"> <h3>Ready to Talk</h3> <button onClick={onConnect} disabled={isConnecting}> {isConnecting ? 'Connecting...' : 'Start Call'} </button> </div> ) }

Key Patterns

1. Categorize errors by recoverability

const isRetryableError = (code) => { return ['NETWORK_ERROR', 'CONNECTION_FAILED', 'CONCURRENCY_LIMIT'].includes(code) }

2. Limit retry attempts

if (retryCount >= 3) { // Stop retrying, show different UI }

3. Provide actionable guidance

Each error type has specific instructions that help users resolve the issue.

Last updated on