SDKError
All SDK errors are represented bySDKError:
Copy
Ask AI
public struct SDKError: Error, LocalizedError, Sendable {
public let code: ErrorCode // Error code enum
public let message: String // Detailed message
public let category: ErrorCategory // Error category
public let stackTrace: [String] // Debug stack trace
public let underlyingError: (any Error)? // Wrapped error
public var errorDescription: String? { get }
public var failureReason: String? { get }
public var recoverySuggestion: String? { get }
}
Error Codes
Copy
Ask AI
public enum ErrorCode: String, Sendable {
// Initialization
case notInitialized
case invalidConfiguration
case invalidAPIKey
case validationFailed
// Models
case modelNotFound
case modelLoadFailed
case modelIncompatible
// Generation
case generationFailed
case processingFailed
case streamingNotSupported
// Audio
case emptyAudioBuffer
case microphonePermissionDenied
// Network
case networkUnavailable
case networkError
case timeout
// Storage
case insufficientStorage
case insufficientMemory
case storageError
// General
case initializationFailed
case cancelled
case invalidState
case invalidInput
case notImplemented
case unknown
}
Error Categories
Copy
Ask AI
public enum ErrorCategory: String, Sendable {
case general
case stt
case tts
case llm
case vad
case voiceAgent
case download
case fileManagement
case network
case authentication
case security
case runtime
}
Basic Error Handling
Copy
Ask AI
do {
let result = try await RunAnywhere.generate("Hello")
print(result.text)
} catch let error as SDKError {
print("Error: \(error.message)")
print("Code: \(error.code)")
print("Category: \(error.category)")
if let suggestion = error.recoverySuggestion {
print("Suggestion: \(suggestion)")
}
} catch {
print("Unexpected error: \(error)")
}
Handling Specific Errors
By Error Code
Copy
Ask AI
do {
let result = try await RunAnywhere.generate(prompt)
} catch let error as SDKError {
switch error.code {
case .notInitialized:
// SDK not initialized
showAlert("Please restart the app")
case .modelNotFound:
// Model not loaded
try await RunAnywhere.loadModel("default-model")
case .modelLoadFailed:
// Model failed to load
showAlert("Failed to load AI model. Try redownloading.")
case .generationFailed:
// Generation failed
showAlert("Generation failed. Please try again.")
case .insufficientMemory:
// Not enough RAM
try await RunAnywhere.unloadModel()
showAlert("Low memory. Some features may be limited.")
case .networkUnavailable:
// No network (may be needed for auth)
showOfflineMode()
case .timeout:
// Operation timed out
showAlert("Request timed out. Please try again.")
case .cancelled:
// User cancelled
break
default:
showAlert("An error occurred: \(error.message)")
}
}
By Category
Copy
Ask AI
do {
let result = try await RunAnywhere.processVoiceTurn(audioData)
} catch let error as SDKError {
switch error.category {
case .llm:
handleLLMError(error)
case .stt:
handleSTTError(error)
case .tts:
handleTTSError(error)
case .network:
handleNetworkError(error)
case .authentication:
handleAuthError(error)
default:
handleGenericError(error)
}
}
Error Factory Methods
The SDK provides factory methods for creating errors:Copy
Ask AI
// Create errors programmatically
SDKError.general(.notInitialized, "SDK not initialized")
SDKError.llm(.generationFailed, "Generation failed", underlying: originalError)
SDKError.stt(.modelNotFound, "STT model not found")
SDKError.tts(.processingFailed, "TTS synthesis failed")
SDKError.network(.networkUnavailable, "No internet connection")
SDKError.authentication(.invalidAPIKey, "Invalid API key")
SwiftUI Error Handling
Copy
Ask AI
struct ContentView: View {
@State private var error: SDKError?
@State private var showError = false
@State private var response = ""
var body: some View {
VStack {
Text(response)
Button("Generate") {
Task { await generate() }
}
}
.alert("Error", isPresented: $showError, presenting: error) { _ in
Button("OK") { error = nil }
} message: { error in
VStack {
Text(error.message)
if let suggestion = error.recoverySuggestion {
Text(suggestion)
.font(.caption)
}
}
}
}
func generate() async {
do {
let result = try await RunAnywhere.generate("Hello")
response = result.text
} catch let sdkError as SDKError {
error = sdkError
showError = true
} catch {
self.error = SDKError.general(.unknown, error.localizedDescription)
showError = true
}
}
}
Error Recovery Strategies
Retry Logic
Copy
Ask AI
func generateWithRetry(
prompt: String,
maxRetries: Int = 3
) async throws -> LLMGenerationResult {
var lastError: Error?
for attempt in 1...maxRetries {
do {
return try await RunAnywhere.generate(prompt)
} catch let error as SDKError {
lastError = error
// Don't retry certain errors
switch error.code {
case .notInitialized, .invalidAPIKey, .modelNotFound:
throw error
case .timeout, .networkError:
// Retry with delay
try await Task.sleep(for: .seconds(Double(attempt)))
default:
throw error
}
}
}
throw lastError ?? SDKError.general(.unknown, "Max retries exceeded")
}
Graceful Degradation
Copy
Ask AI
func generateResponse(_ prompt: String) async -> String {
do {
let result = try await RunAnywhere.generate(prompt)
return result.text
} catch let error as SDKError {
switch error.code {
case .modelNotFound:
return "Please wait while the AI model loads..."
case .insufficientMemory:
return "Memory is low. Please close other apps and try again."
case .timeout:
return "The request took too long. Please try a shorter prompt."
default:
return "I'm having trouble responding right now. Please try again."
}
} catch {
return "An unexpected error occurred."
}
}
Model Fallback
Copy
Ask AI
func generateWithFallback(_ prompt: String) async throws -> String {
// Try primary model
do {
return try await RunAnywhere.chat(prompt)
} catch let error as SDKError where error.code == .generationFailed {
// Try smaller model
try await RunAnywhere.unloadModel()
try await RunAnywhere.loadModel("llama-3.2-1b-instruct-q4") // Smaller model
return try await RunAnywhere.chat(prompt)
}
}
Logging Errors
Copy
Ask AI
func logError(_ error: SDKError) {
print("""
=== SDK Error ===
Code: \(error.code.rawValue)
Category: \(error.category.rawValue)
Message: \(error.message)
Suggestion: \(error.recoverySuggestion ?? "None")
Stack: \(error.stackTrace.joined(separator: "\n"))
Underlying: \(error.underlyingError?.localizedDescription ?? "None")
================
""")
}
Event-Based Error Handling
Subscribe to error events SDK-wide:Copy
Ask AI
import Combine
class ErrorHandler {
private var cancellables = Set<AnyCancellable>()
init() {
// Subscribe to all errors
RunAnywhere.events.events
.compactMap { $0 as? ErrorEvent }
.sink { event in
self.handleError(event.error)
}
.store(in: &cancellables)
}
private func handleError(_ error: Error) {
// Log to analytics, show UI, etc.
}
}
Best Practices
Always catch SDKError
Always catch SDKError
Catch
SDKError specifically to access detailed error information.Provide user-friendly messages
Provide user-friendly messages
Use
recoverySuggestion when available, or map error codes to friendly messages.Log errors for debugging
Log errors for debugging
Log full error details including stack traces in development builds.
Implement recovery
Implement recovery
Where possible, implement automatic recovery (retries, fallbacks).