Skip to main content
Glama
exceptions.py13.4 kB
"""Custom exception classes for the application. This module defines all custom exceptions used throughout the application, providing consistent error handling and messaging. """ from typing import Any class BaseDocxException(Exception): """Base exception for all application exceptions. Attributes: message: Human-readable error message. code: Error code for API responses. status_code: HTTP status code. details: Additional error details. """ def __init__( self, message: str = "An error occurred", code: str = "ERROR", status_code: int = 500, details: dict[str, Any] | None = None, ) -> None: """Initialize the exception. Args: message: Human-readable error message. code: Error code for API responses. status_code: HTTP status code. details: Additional error details. """ super().__init__(message) self.message = message self.code = code self.status_code = status_code self.details = details or {} def to_dict(self) -> dict[str, Any]: """Convert exception to dictionary for API responses. Returns: Dictionary representation of the exception. """ return { "error": { "code": self.code, "message": self.message, "details": self.details, } } class DocumentNotFoundError(BaseDocxException): """Exception raised when a document is not found. Attributes: document_id: ID of the document that was not found. """ def __init__( self, document_id: str | int | None = None, message: str = "Document not found", ) -> None: """Initialize the exception. Args: document_id: ID of the document that was not found. message: Human-readable error message. """ details = {"document_id": document_id} if document_id else {} super().__init__( message=message, code="DOCUMENT_NOT_FOUND", status_code=404, details=details, ) self.document_id = document_id class TemplateNotFoundError(BaseDocxException): """Exception raised when a template is not found. Attributes: template_id: ID of the template that was not found. """ def __init__( self, template_id: str | int | None = None, message: str = "Template not found", ) -> None: """Initialize the exception. Args: template_id: ID of the template that was not found. message: Human-readable error message. """ details = {"template_id": template_id} if template_id else {} super().__init__( message=message, code="TEMPLATE_NOT_FOUND", status_code=404, details=details, ) self.template_id = template_id class InvalidDocumentError(BaseDocxException): """Exception raised when a document is invalid or corrupted.""" def __init__( self, message: str = "Invalid document format", details: dict[str, Any] | None = None, ) -> None: """Initialize the exception. Args: message: Human-readable error message. details: Additional error details. """ super().__init__( message=message, code="INVALID_DOCUMENT", status_code=400, details=details or {}, ) class DocumentProcessingError(BaseDocxException): """Exception raised when document processing fails.""" def __init__( self, message: str = "Document processing failed", details: dict[str, Any] | None = None, ) -> None: """Initialize the exception. Args: message: Human-readable error message. details: Additional error details. """ super().__init__( message=message, code="DOCUMENT_PROCESSING_ERROR", status_code=500, details=details or {}, ) class PermissionDeniedError(BaseDocxException): """Exception raised when user lacks required permissions.""" def __init__( self, message: str = "Permission denied", required_permission: str | None = None, ) -> None: """Initialize the exception. Args: message: Human-readable error message. required_permission: The permission that was required. """ details = ( {"required_permission": required_permission} if required_permission else {} ) super().__init__( message=message, code="PERMISSION_DENIED", status_code=403, details=details, ) class ValidationError(BaseDocxException): """Exception raised when validation fails.""" def __init__( self, message: str = "Validation failed", errors: list[dict[str, Any]] | None = None, ) -> None: """Initialize the exception. Args: message: Human-readable error message. errors: List of validation errors. """ super().__init__( message=message, code="VALIDATION_ERROR", status_code=422, details={"errors": errors or []}, ) self.errors = errors or [] class AuthenticationError(BaseDocxException): """Exception raised when authentication fails.""" def __init__( self, message: str = "Authentication required", ) -> None: """Initialize the exception. Args: message: Human-readable error message. """ super().__init__( message=message, code="AUTHENTICATION_REQUIRED", status_code=401, ) class TokenExpiredError(BaseDocxException): """Exception raised when a token has expired.""" def __init__( self, message: str = "Token has expired", ) -> None: """Initialize the exception. Args: message: Human-readable error message. """ super().__init__( message=message, code="TOKEN_EXPIRED", status_code=401, ) class InvalidTokenError(BaseDocxException): """Exception raised when a token is invalid.""" def __init__( self, message: str = "Invalid token", ) -> None: """Initialize the exception. Args: message: Human-readable error message. """ super().__init__( message=message, code="INVALID_TOKEN", status_code=401, ) class RateLimitExceededError(BaseDocxException): """Exception raised when rate limit is exceeded.""" def __init__( self, message: str = "Rate limit exceeded", retry_after: int | None = None, ) -> None: """Initialize the exception. Args: message: Human-readable error message. retry_after: Seconds until rate limit resets. """ details = {"retry_after": retry_after} if retry_after else {} super().__init__( message=message, code="RATE_LIMIT_EXCEEDED", status_code=429, details=details, ) class FileTooLargeError(BaseDocxException): """Exception raised when a file exceeds the size limit.""" def __init__( self, message: str = "File size exceeds maximum limit", max_size: int | None = None, actual_size: int | None = None, ) -> None: """Initialize the exception. Args: message: Human-readable error message. max_size: Maximum allowed file size in bytes. actual_size: Actual file size in bytes. """ details: dict[str, Any] = {} if max_size: details["max_size"] = max_size if actual_size: details["actual_size"] = actual_size super().__init__( message=message, code="FILE_TOO_LARGE", status_code=413, details=details, ) class UnsupportedFormatError(BaseDocxException): """Exception raised when a file format is not supported.""" def __init__( self, message: str = "Unsupported file format", format_: str | None = None, supported_formats: list[str] | None = None, ) -> None: """Initialize the exception. Args: message: Human-readable error message. format_: The unsupported format. supported_formats: List of supported formats. """ details: dict[str, Any] = {} if format_: details["format"] = format_ if supported_formats: details["supported_formats"] = supported_formats super().__init__( message=message, code="UNSUPPORTED_FORMAT", status_code=415, details=details, ) class DuplicateResourceError(BaseDocxException): """Exception raised when attempting to create a duplicate resource.""" def __init__( self, message: str = "Resource already exists", resource_type: str | None = None, identifier: str | None = None, ) -> None: """Initialize the exception. Args: message: Human-readable error message. resource_type: Type of the resource. identifier: Resource identifier. """ details: dict[str, Any] = {} if resource_type: details["resource_type"] = resource_type if identifier: details["identifier"] = identifier super().__init__( message=message, code="DUPLICATE_RESOURCE", status_code=409, details=details, ) class OperationTimeoutError(BaseDocxException): """Exception raised when an operation times out.""" def __init__( self, message: str = "Operation timed out", operation: str | None = None, timeout_seconds: int | None = None, ) -> None: """Initialize the exception. Args: message: Human-readable error message. operation: The operation that timed out. timeout_seconds: Timeout duration in seconds. """ details: dict[str, Any] = {} if operation: details["operation"] = operation if timeout_seconds: details["timeout_seconds"] = timeout_seconds super().__init__( message=message, code="OPERATION_TIMEOUT", status_code=504, details=details, ) class ExternalServiceError(BaseDocxException): """Exception raised when an external service fails.""" def __init__( self, message: str = "External service error", service: str | None = None, ) -> None: """Initialize the exception. Args: message: Human-readable error message. service: Name of the external service. """ details = {"service": service} if service else {} super().__init__( message=message, code="EXTERNAL_SERVICE_ERROR", status_code=502, details=details, ) class DocumentLockError(BaseDocxException): """Exception raised when a document is locked by another user.""" def __init__( self, message: str = "Document is locked by another user", locked_by: str | None = None, lock_expires: str | None = None, ) -> None: """Initialize the exception. Args: message: Human-readable error message. locked_by: User who holds the lock. lock_expires: Lock expiration timestamp. """ details: dict[str, Any] = {} if locked_by: details["locked_by"] = locked_by if lock_expires: details["lock_expires"] = lock_expires super().__init__( message=message, code="DOCUMENT_LOCKED", status_code=423, details=details, ) class VersionConflictError(BaseDocxException): """Exception raised when there's a version conflict.""" def __init__( self, message: str = "Version conflict detected", current_version: int | None = None, expected_version: int | None = None, ) -> None: """Initialize the exception. Args: message: Human-readable error message. current_version: Current version of the resource. expected_version: Expected version for the operation. """ details: dict[str, Any] = {} if current_version is not None: details["current_version"] = current_version if expected_version is not None: details["expected_version"] = expected_version super().__init__( message=message, code="VERSION_CONFLICT", status_code=409, details=details, )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Fu-Jie/MCP-OPENAPI-DOCX'

If you have feedback or need assistance with the MCP directory API, please join our Discord server