"""Exceptions used across the voice-clone app.""" from __future__ import annotations class VoiceCloneError(Exception): """Base class — user-readable by default.""" def __init__(self, message: str, *, provider_response: str | None = None): super().__init__(message) self.message = message self.provider_response = provider_response def __str__(self) -> str: return self.message class ConfigError(VoiceCloneError): """Raised when required configuration (API key, base URL) is missing.""" class ReferenceAudioError(VoiceCloneError): """Raised when the user-supplied reference audio is unusable.""" class UnsupportedLanguageError(VoiceCloneError): """Raised when the requested language isn't exposed by any provider.""" class ProviderHTTPError(VoiceCloneError): """Raised when the backend returns a non-success HTTP response.""" def __init__(self, message: str, *, status_code: int, provider_response: str | None = None): super().__init__(message, provider_response=provider_response) self.status_code = status_code class ProviderTimeoutError(VoiceCloneError): """Raised when the backend takes too long to respond.""" class ProviderUnavailableError(VoiceCloneError): """Raised when the backend is unreachable / DNS / connection refused."""