"""Base error handling infrastructure for authorization, network, and validation errors.""" from typing import Optional class PrometheusError(Exception): """Base exception for Prometheus-related errors.""" pass class AuthorizationError(PrometheusError): """Raised when authorization or configuration fails (e.g. missing observability URL).""" def __init__(self, message: str = "Access denied: observability URL is required"): self.message = message super().__init__(self.message) class NetworkError(PrometheusError): """Raised when network connection to Prometheus fails.""" def __init__( self, message: str = ( "Prometheus backend is unreachable. Please verify the observability URL " "and network connectivity." ), ): self.message = message super().__init__(self.message) class ValidationError(PrometheusError): """Raised when input validation fails.""" def __init__(self, message: str): self.message = message super().__init__(self.message) class PrometheusTimeoutError(PrometheusError): """Raised when Prometheus request times out.""" def __init__(self, message: str = "Query exceeded 20-second timeout"): self.message = message super().__init__(self.message) class PrometheusAPIError(PrometheusError): """Raised when Prometheus API returns an error.""" def __init__(self, message: str, prometheus_error: Optional[str] = None): self.message = message self.prometheus_error = prometheus_error if prometheus_error: full_message = f"Invalid range query parameters. Error details: {prometheus_error}" else: full_message = message super().__init__(full_message) def __str__(self) -> str: """Return formatted error message.""" return ( self.message if not self.prometheus_error else f"{self.message}. Error details: {self.prometheus_error}" ) class DeltaError(PrometheusError): """Raised when DuckDB/Delta Lake read fails (e.g. missing extension, I/O, auth).""" def __init__(self, message: str): self.message = message super().__init__(self.message) class AuthServiceError(PrometheusError): """Raised when the backend auth service fails or returns an error.""" def __init__(self, message: str, status_code: Optional[int] = None): self.message = message self.status_code = status_code super().__init__(self.message) class LokiAPIError(PrometheusError): """Raised when Loki API returns an error.""" def __init__(self, message: str, loki_error: Optional[str] = None): self.message = message self.loki_error = loki_error if loki_error: full_message = f"{message}. Error details: {loki_error}" else: full_message = message super().__init__(full_message) def __str__(self) -> str: """Return formatted error message.""" return ( self.message if not self.loki_error else f"{self.message}. Error details: {self.loki_error}" ) class LokiTimeoutError(PrometheusError): """Raised when Loki request times out.""" def __init__(self, message: str = "Loki query timeout"): self.message = message super().__init__(self.message)