Overview
The RunAnywhere SDK provides structured error handling throughSDKError with specific error codes and categories. This guide covers error types, handling patterns, and recovery strategies.
SDKError Structure
interface SDKError extends Error {
/** Unique error code */
code: SDKErrorCode
/** Error category */
category: ErrorCategory
/** Original error (if wrapped) */
underlyingError?: Error
/** Additional context */
context?: ErrorContext
/** Suggested recovery action */
recoverySuggestion?: string
}
Checking for SDK Errors
import { isSDKError, SDKError, SDKErrorCode } from '@runanywhere/core'
try {
await RunAnywhere.generate('Hello')
} catch (error) {
if (isSDKError(error)) {
// Handle SDK-specific error
console.log('Code:', error.code)
console.log('Category:', error.category)
console.log('Message:', error.message)
console.log('Recovery:', error.recoverySuggestion)
} else {
// Handle generic error
console.error('Unexpected error:', error)
}
}
Error Codes
General Errors
| Code | Description | Recovery |
|---|---|---|
notInitialized | SDK not initialized | Call RunAnywhere.initialize() |
alreadyInitialized | SDK already initialized | Use existing instance or call reset() |
invalidInput | Invalid input parameters | Check input values |
nativeModuleNotAvailable | Native module not linked | Rebuild app, check pod install |
Model Errors
| Code | Description | Recovery |
|---|---|---|
modelNotFound | Model not in registry | Add model with LlamaCPP.addModel() |
modelLoadFailed | Failed to load model | Check model path, format, memory |
modelNotLoaded | No model loaded | Call loadModel() first |
modelDownloadFailed | Download failed | Check network, retry |
Generation Errors
| Code | Description | Recovery |
|---|---|---|
generationFailed | Text generation failed | Check model, reduce tokens |
generationCancelled | Generation was cancelled | Expected if cancelGeneration() called |
Voice Errors
| Code | Description | Recovery |
|---|---|---|
sttFailed | Transcription failed | Check audio format, model |
ttsFailed | Synthesis failed | Check TTS model, text |
vadFailed | VAD failed | Check VAD configuration |
voiceAgentFailed | Voice pipeline failed | Check all models loaded |
Resource Errors
| Code | Description | Recovery |
|---|---|---|
insufficientStorage | Not enough disk space | Free storage, delete models |
insufficientMemory | Not enough RAM | Unload models, use smaller model |
downloadFailed | Download failed | Check network, storage |
downloadCancelled | Download cancelled | Expected if cancelled by user |
Network/Auth Errors
| Code | Description | Recovery |
|---|---|---|
networkUnavailable | No network connection | Check connectivity |
authenticationFailed | Invalid API key | Check API key |
permissionDenied | Missing permission | Request permission |
Error Categories
enum ErrorCategory {
General = 'general',
LLM = 'llm',
STT = 'stt',
TTS = 'tts',
VAD = 'vad',
VoiceAgent = 'voiceAgent',
Download = 'download',
Network = 'network',
Authentication = 'authentication',
Storage = 'storage',
Memory = 'memory',
}
Handling Patterns
Comprehensive Error Handler
import { isSDKError, SDKError, SDKErrorCode, ErrorCategory } from '@runanywhere/core'
async function handleSDKOperation<T>(
operation: () => Promise<T>,
options?: {
onRetry?: () => void
maxRetries?: number
}
): Promise<T> {
const maxRetries = options?.maxRetries ?? 1
let lastError: Error | null = null
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await operation()
} catch (error) {
lastError = error as Error
if (!isSDKError(error)) {
throw error // Non-SDK error, don't retry
}
// Handle specific errors
switch (error.code) {
// Retryable errors
case SDKErrorCode.networkUnavailable:
case SDKErrorCode.downloadFailed:
if (attempt < maxRetries) {
options?.onRetry?.()
await delay(1000 * (attempt + 1)) // Exponential backoff
continue
}
break
// Non-retryable errors
case SDKErrorCode.notInitialized:
case SDKErrorCode.modelNotFound:
case SDKErrorCode.invalidInput:
case SDKErrorCode.insufficientStorage:
throw error
// Memory errors - try recovery
case SDKErrorCode.insufficientMemory:
await RunAnywhere.unloadModel()
if (attempt < maxRetries) {
continue
}
break
}
throw error
}
}
throw lastError
}
function delay(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms))
}
Category-Based Handling
function handleError(error: SDKError): string {
switch (error.category) {
case ErrorCategory.LLM:
return handleLLMError(error)
case ErrorCategory.STT:
return handleSTTError(error)
case ErrorCategory.TTS:
return handleTTSError(error)
case ErrorCategory.Network:
return 'Please check your internet connection.'
case ErrorCategory.Storage:
return 'Not enough storage space. Please free up some space.'
case ErrorCategory.Memory:
return 'Not enough memory. Try closing other apps.'
default:
return error.recoverySuggestion || error.message
}
}
function handleLLMError(error: SDKError): string {
switch (error.code) {
case SDKErrorCode.modelNotLoaded:
return 'Please wait for the AI model to load.'
case SDKErrorCode.generationFailed:
return 'Failed to generate response. Please try again.'
case SDKErrorCode.generationCancelled:
return 'Generation was cancelled.'
default:
return 'An error occurred with the AI model.'
}
}
React Hook for Error Handling
useSDKError.ts
import { useState, useCallback } from 'react'
import { isSDKError, SDKError, SDKErrorCode } from '@runanywhere/core'
interface ErrorState {
error: SDKError | Error | null
userMessage: string | null
canRetry: boolean
}
export function useSDKError() {
const [errorState, setErrorState] = useState<ErrorState>({
error: null,
userMessage: null,
canRetry: false,
})
const handleError = useCallback((error: unknown) => {
if (isSDKError(error)) {
const canRetry = [
SDKErrorCode.networkUnavailable,
SDKErrorCode.downloadFailed,
SDKErrorCode.generationFailed,
].includes(error.code)
setErrorState({
error,
userMessage: getErrorMessage(error),
canRetry,
})
} else {
setErrorState({
error: error as Error,
userMessage: 'An unexpected error occurred.',
canRetry: false,
})
}
}, [])
const clearError = useCallback(() => {
setErrorState({ error: null, userMessage: null, canRetry: false })
}, [])
return { ...errorState, handleError, clearError }
}
function getErrorMessage(error: SDKError): string {
// Return user-friendly messages based on error code
switch (error.code) {
case SDKErrorCode.notInitialized:
return 'The app is still loading. Please wait.'
case SDKErrorCode.modelNotLoaded:
return 'The AI model is not ready yet.'
case SDKErrorCode.networkUnavailable:
return 'No internet connection.'
case SDKErrorCode.insufficientMemory:
return 'Not enough memory. Try closing other apps.'
case SDKErrorCode.insufficientStorage:
return 'Not enough storage space.'
default:
return error.recoverySuggestion || error.message
}
}
Error Display Component
ErrorDisplay.tsx
import React from 'react'
import { View, Text, Button, StyleSheet } from 'react-native'
import { SDKError } from '@runanywhere/core'
interface Props {
error: SDKError | Error
message: string
canRetry: boolean
onRetry?: () => void
onDismiss?: () => void
}
export function ErrorDisplay({ error, message, canRetry, onRetry, onDismiss }: Props) {
return (
<View style={styles.container}>
<Text style={styles.icon}>⚠️</Text>
<Text style={styles.message}>{message}</Text>
<View style={styles.buttons}>
{canRetry && onRetry && <Button title="Retry" onPress={onRetry} />}
{onDismiss && <Button title="Dismiss" onPress={onDismiss} color="#666" />}
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
padding: 16,
backgroundColor: '#fff3cd',
borderRadius: 8,
alignItems: 'center',
},
icon: { fontSize: 32, marginBottom: 8 },
message: { fontSize: 16, textAlign: 'center', marginBottom: 16 },
buttons: { flexDirection: 'row', gap: 8 },
})
Creating Custom Errors
import {
notInitializedError,
modelNotFoundError,
modelLoadError,
generationError,
networkError,
} from '@runanywhere/core'
// Use factory functions
throw notInitializedError()
throw modelNotFoundError('my-model-id')
throw generationError('Context window exceeded')
Logging Errors
import { SDKLogger } from '@runanywhere/core'
const logger = new SDKLogger('MyApp')
try {
await RunAnywhere.generate(prompt)
} catch (error) {
if (isSDKError(error)) {
logger.error('SDK Error', error, {
code: error.code,
category: error.category,
})
} else {
logger.error('Unexpected error', error as Error)
}
}
Related
Configuration
SDK configuration
Best Practices
Optimization tips