| from typing import Optional | |
| class GCPError(Exception): | |
| def __init__(self, message: str, cause: Optional[Exception] = None) -> None: | |
| super().__init__(message) | |
| self.cause = cause | |
| def __str__(self) -> str: | |
| base = super().__str__() | |
| return f"{base} (caused by: {self.cause})" if self.cause else base | |
| class AuthenticationError(GCPError): | |
| pass | |
| class ResourceNotFoundError(GCPError): | |
| def __init__(self, resource_type: str, name: str) -> None: | |
| super().__init__(f"{resource_type} not found: {name}") | |
| self.resource_type = resource_type | |
| self.name = name | |
| class QuotaExceededError(GCPError): | |
| pass | |
| class PermissionDeniedError(GCPError): | |
| pass | |
| class RetryableError(GCPError): | |
| def __init__(self, message: str, attempt: int, cause: Optional[Exception] = None) -> None: | |
| super().__init__(message, cause) | |
| self.attempt = attempt | |
| class TimeoutError(GCPError): | |
| pass | |