Phase 2 build initial
This commit is contained in:
		
							
								
								
									
										184
									
								
								hcfs-python/hcfs/sdk/exceptions.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								hcfs-python/hcfs/sdk/exceptions.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| """ | ||||
| HCFS SDK Exception Classes | ||||
|  | ||||
| Comprehensive exception hierarchy for error handling. | ||||
| """ | ||||
|  | ||||
| from typing import Optional, Dict, Any | ||||
|  | ||||
|  | ||||
| class HCFSError(Exception): | ||||
|     """Base exception for all HCFS SDK errors.""" | ||||
|      | ||||
|     def __init__(self, message: str, error_code: Optional[str] = None, details: Optional[Dict[str, Any]] = None): | ||||
|         super().__init__(message) | ||||
|         self.message = message | ||||
|         self.error_code = error_code | ||||
|         self.details = details or {} | ||||
|      | ||||
|     def __str__(self) -> str: | ||||
|         if self.error_code: | ||||
|             return f"[{self.error_code}] {self.message}" | ||||
|         return self.message | ||||
|      | ||||
|     def to_dict(self) -> Dict[str, Any]: | ||||
|         """Convert exception to dictionary for serialization.""" | ||||
|         return { | ||||
|             "type": self.__class__.__name__, | ||||
|             "message": self.message, | ||||
|             "error_code": self.error_code, | ||||
|             "details": self.details | ||||
|         } | ||||
|  | ||||
|  | ||||
| class HCFSConnectionError(HCFSError): | ||||
|     """Raised when connection to HCFS API fails.""" | ||||
|      | ||||
|     def __init__(self, message: str = "Failed to connect to HCFS API", **kwargs): | ||||
|         super().__init__(message, error_code="CONNECTION_FAILED", **kwargs) | ||||
|  | ||||
|  | ||||
| class HCFSAuthenticationError(HCFSError): | ||||
|     """Raised when authentication fails.""" | ||||
|      | ||||
|     def __init__(self, message: str = "Authentication failed", **kwargs): | ||||
|         super().__init__(message, error_code="AUTH_FAILED", **kwargs) | ||||
|  | ||||
|  | ||||
| class HCFSAuthorizationError(HCFSError): | ||||
|     """Raised when user lacks permissions for an operation.""" | ||||
|      | ||||
|     def __init__(self, message: str = "Insufficient permissions", **kwargs): | ||||
|         super().__init__(message, error_code="INSUFFICIENT_PERMISSIONS", **kwargs) | ||||
|  | ||||
|  | ||||
| class HCFSNotFoundError(HCFSError): | ||||
|     """Raised when a requested resource is not found.""" | ||||
|      | ||||
|     def __init__(self, resource_type: str = "Resource", resource_id: str = "", **kwargs): | ||||
|         message = f"{resource_type} not found" | ||||
|         if resource_id: | ||||
|             message += f": {resource_id}" | ||||
|         super().__init__(message, error_code="NOT_FOUND", **kwargs) | ||||
|  | ||||
|  | ||||
| class HCFSValidationError(HCFSError): | ||||
|     """Raised when request validation fails.""" | ||||
|      | ||||
|     def __init__(self, message: str = "Request validation failed", validation_errors: Optional[list] = None, **kwargs): | ||||
|         super().__init__(message, error_code="VALIDATION_FAILED", **kwargs) | ||||
|         self.validation_errors = validation_errors or [] | ||||
|      | ||||
|     def to_dict(self) -> Dict[str, Any]: | ||||
|         result = super().to_dict() | ||||
|         result["validation_errors"] = self.validation_errors | ||||
|         return result | ||||
|  | ||||
|  | ||||
| class HCFSRateLimitError(HCFSError): | ||||
|     """Raised when rate limit is exceeded.""" | ||||
|      | ||||
|     def __init__(self, retry_after: Optional[int] = None, **kwargs): | ||||
|         message = "Rate limit exceeded" | ||||
|         if retry_after: | ||||
|             message += f". Retry after {retry_after} seconds" | ||||
|         super().__init__(message, error_code="RATE_LIMIT_EXCEEDED", **kwargs) | ||||
|         self.retry_after = retry_after | ||||
|  | ||||
|  | ||||
| class HCFSServerError(HCFSError): | ||||
|     """Raised for server-side errors (5xx status codes).""" | ||||
|      | ||||
|     def __init__(self, message: str = "Internal server error", status_code: Optional[int] = None, **kwargs): | ||||
|         super().__init__(message, error_code="SERVER_ERROR", **kwargs) | ||||
|         self.status_code = status_code | ||||
|  | ||||
|  | ||||
| class HCFSTimeoutError(HCFSError): | ||||
|     """Raised when a request times out.""" | ||||
|      | ||||
|     def __init__(self, operation: str = "Request", timeout_seconds: Optional[float] = None, **kwargs): | ||||
|         message = f"{operation} timed out" | ||||
|         if timeout_seconds: | ||||
|             message += f" after {timeout_seconds}s" | ||||
|         super().__init__(message, error_code="TIMEOUT", **kwargs) | ||||
|         self.timeout_seconds = timeout_seconds | ||||
|  | ||||
|  | ||||
| class HCFSCacheError(HCFSError): | ||||
|     """Raised for cache-related errors.""" | ||||
|      | ||||
|     def __init__(self, message: str = "Cache operation failed", **kwargs): | ||||
|         super().__init__(message, error_code="CACHE_ERROR", **kwargs) | ||||
|  | ||||
|  | ||||
| class HCFSBatchError(HCFSError): | ||||
|     """Raised for batch operation errors.""" | ||||
|      | ||||
|     def __init__(self, message: str = "Batch operation failed", failed_items: Optional[list] = None, **kwargs): | ||||
|         super().__init__(message, error_code="BATCH_ERROR", **kwargs) | ||||
|         self.failed_items = failed_items or [] | ||||
|      | ||||
|     def to_dict(self) -> Dict[str, Any]: | ||||
|         result = super().to_dict() | ||||
|         result["failed_items"] = self.failed_items | ||||
|         return result | ||||
|  | ||||
|  | ||||
| class HCFSStreamError(HCFSError): | ||||
|     """Raised for streaming/WebSocket errors.""" | ||||
|      | ||||
|     def __init__(self, message: str = "Stream operation failed", **kwargs): | ||||
|         super().__init__(message, error_code="STREAM_ERROR", **kwargs) | ||||
|  | ||||
|  | ||||
| class HCFSSearchError(HCFSError): | ||||
|     """Raised for search operation errors.""" | ||||
|      | ||||
|     def __init__(self, query: str = "", search_type: str = "", **kwargs): | ||||
|         message = f"Search failed" | ||||
|         if search_type: | ||||
|             message += f" ({search_type})" | ||||
|         if query: | ||||
|             message += f": '{query}'" | ||||
|         super().__init__(message, error_code="SEARCH_ERROR", **kwargs) | ||||
|         self.query = query | ||||
|         self.search_type = search_type | ||||
|  | ||||
|  | ||||
| def handle_api_error(response) -> None: | ||||
|     """ | ||||
|     Convert HTTP response errors to appropriate HCFS exceptions. | ||||
|      | ||||
|     Args: | ||||
|         response: HTTP response object | ||||
|          | ||||
|     Raises: | ||||
|         Appropriate HCFSError subclass based on status code | ||||
|     """ | ||||
|     status_code = response.status_code | ||||
|      | ||||
|     try: | ||||
|         error_data = response.json() if response.content else {} | ||||
|     except Exception: | ||||
|         error_data = {} | ||||
|      | ||||
|     error_message = error_data.get("error", "Unknown error") | ||||
|     error_details = error_data.get("error_details", []) | ||||
|      | ||||
|     if status_code == 400: | ||||
|         raise HCFSValidationError(error_message, validation_errors=error_details) | ||||
|     elif status_code == 401: | ||||
|         raise HCFSAuthenticationError(error_message) | ||||
|     elif status_code == 403: | ||||
|         raise HCFSAuthorizationError(error_message) | ||||
|     elif status_code == 404: | ||||
|         raise HCFSNotFoundError("Resource", error_message) | ||||
|     elif status_code == 429: | ||||
|         retry_after = response.headers.get("Retry-After") | ||||
|         retry_after = int(retry_after) if retry_after else None | ||||
|         raise HCFSRateLimitError(retry_after=retry_after) | ||||
|     elif 500 <= status_code < 600: | ||||
|         raise HCFSServerError(error_message, status_code=status_code) | ||||
|     else: | ||||
|         raise HCFSError(f"HTTP {status_code}: {error_message}") | ||||
		Reference in New Issue
	
	Block a user
	 Claude Code
					Claude Code