nifty-coder/stemsplit-backend
0
1"""2Custom exceptions for the voice control optimization system.3 4This module defines all custom exceptions used throughout the voice control5system to provide clear error handling and debugging information.6"""7 8 9class VoiceControlError(Exception):10 """Base exception for all voice control system errors."""11 12 def __init__(self, message: str, error_code: str = None, details: dict = None):13 super().__init__(message)14 self.message = message15 self.error_code = error_code or self.__class__.__name__16 self.details = details or {}17 18 19class ProviderError(VoiceControlError):20 """Base exception for STT provider errors."""21 22 def __init__(self, provider: str, message: str, error_code: str = None, details: dict = None):23 super().__init__(message, error_code, details)24 self.provider = provider25 26 27class ProviderUnavailableError(ProviderError):28 """Raised when a provider is unavailable or unhealthy."""29 pass30 31 32class ProviderTimeoutError(ProviderError):33 """Raised when a provider request times out."""34 pass35 36 37class ProviderAuthenticationError(ProviderError):38 """Raised when provider authentication fails."""39 pass40 41 42class QuotaExceededError(ProviderError):43 """Raised when provider quota limits are exceeded."""44 45 def __init__(self, provider: str, quota_type: str, current_usage: float, limit: float):46 message = f"Quota exceeded for {provider}: {quota_type} usage {current_usage} >= limit {limit}"47 super().__init__(provider, message)48 self.quota_type = quota_type49 self.current_usage = current_usage50 self.limit = limit51 52 53class RateLimitExceededError(ProviderError):54 """Raised when provider rate limits are exceeded."""55 56 def __init__(self, provider: str, quota_type: str = None, retry_after: float = None):57 message = f"Rate limit exceeded for {provider}"58 if quota_type:59 message += f" ({quota_type})"60 if retry_after:61 message += f", retry after {retry_after:.1f} seconds"62 super().__init__(provider, message)63 self.quota_type = quota_type64 self.retry_after = retry_after65 66 67class UnsupportedFormatError(ProviderError):68 """Raised when a provider doesn't support the requested audio format."""69 70 def __init__(self, provider: str, format: str, supported_formats: list = None):71 message = f"Provider {provider} does not support format '{format}'"72 if supported_formats:73 message += f", supported formats: {', '.join(supported_formats)}"74 super().__init__(provider, message)75 self.format = format76 self.supported_formats = supported_formats or []77 78 79class UnsupportedLanguageError(ProviderError):80 """Raised when a provider doesn't support the requested language."""81 82 def __init__(self, provider: str, language: str, supported_languages: list = None):83 message = f"Provider {provider} does not support language '{language}'"84 if supported_languages:85 message += f", supported languages: {', '.join(supported_languages)}"86 super().__init__(provider, message)87 self.language = language88 self.supported_languages = supported_languages or []89 90 91class AudioProcessingError(VoiceControlError):92 """Raised when audio processing operations fail."""93 94 def __init__(self, operation: str, message: str, details: dict = None):95 super().__init__(f"Audio processing failed during {operation}: {message}", details=details)96 self.operation = operation97 98 99class AudioFormatError(AudioProcessingError):100 """Raised when audio format conversion fails."""101 102 def __init__(self, source_format: str, target_format: str, message: str):103 super().__init__(104 "format_conversion",105 f"Failed to convert from {source_format} to {target_format}: {message}"106 )107 self.source_format = source_format108 self.target_format = target_format109 110 111class CacheError(VoiceControlError):112 """Base exception for cache-related errors."""113 pass114 115 116class CacheKeyError(CacheError):117 """Raised when cache key generation fails."""118 pass119 120 121class CacheStorageError(CacheError):122 """Raised when cache storage operations fail."""123 pass124 125 126class ConfigurationError(VoiceControlError):127 """Raised when configuration is invalid or missing."""128 129 def __init__(self, config_key: str, message: str, details: dict = None):130 super().__init__(f"Configuration error for '{config_key}': {message}", details=details)131 self.config_key = config_key132 133 134class ValidationError(VoiceControlError):135 """Raised when data validation fails."""136 137 def __init__(self, field: str, value: any, message: str):138 super().__init__(f"Validation failed for field '{field}' with value '{value}': {message}")139 self.field = field140 self.value = value141 142 143class CircuitBreakerError(ProviderError):144 """Raised when a provider's circuit breaker is open."""145 146 def __init__(self, provider: str, failure_count: int, threshold: int):147 message = f"Circuit breaker open for {provider}: {failure_count} failures >= {threshold} threshold"148 super().__init__(provider, message)149 self.failure_count = failure_count150 self.threshold = threshold151 152 153class NoProvidersAvailableError(VoiceControlError):154 """Raised when no providers are available for transcription."""155 156 def __init__(self, attempted_providers: list = None):157 message = "No providers available for transcription"158 if attempted_providers:159 message += f", attempted: {', '.join(attempted_providers)}"160 super().__init__(message)161 self.attempted_providers = attempted_providers or []162 163 164class TranscriptionError(VoiceControlError):165 """Raised when transcription fails for non-provider-specific reasons."""166 167 def __init__(self, message: str, confidence: float = None, partial_result: str = None):168 super().__init__(message)169 self.confidence = confidence170 self.partial_result = partial_result171 172 173class CostMonitoringError(VoiceControlError):174 """Raised when cost monitoring operations fail."""175 pass176 177 178class BudgetExceededError(CostMonitoringError):179 """Raised when budget thresholds are exceeded."""180 181 def __init__(self, provider: str, current_cost: float, threshold: float, time_period: str):182 message = f"Budget exceeded for {provider}: ${current_cost:.2f} >= ${threshold:.2f} for {time_period}"183 super().__init__(message)184 self.provider = provider185 self.current_cost = current_cost186 self.threshold = threshold187 self.time_period = time_period