class ProviderError(Exception): """Base provider exception.""" class ProviderTransientError(ProviderError): """Temporary provider failure that can be retried.""" class ProviderUnauthorizedError(ProviderError): """Raised when provider credentials are valid format but not authorized for an endpoint.""" def __init__(self, *, provider: str, path: str, status_code: int, detail: str = ""): super().__init__(f"{provider} unauthorized status={status_code} path={path} detail={detail}") self.provider = provider self.path = path self.status_code = status_code self.detail = detail class ProviderRateLimitError(ProviderTransientError): """Raised when provider rate limit is hit.""" def __init__(self, message: str, retry_after_seconds: int = 30): super().__init__(message) self.retry_after_seconds = retry_after_seconds class ProviderNotFoundError(ProviderError): """Raised when an unknown provider namespace is requested."""