.. _exceptions: ========== Exceptions ========== QuantumEngine provides a comprehensive exception hierarchy for handling errors across different database backends and operations. .. contents:: Table of Contents :local: :depth: 2 Overview -------- QuantumEngine's exception system provides: * **Consistent error handling** across different backends * **Specific exception types** for different error categories * **Detailed error information** for debugging and logging * **Backend-specific exceptions** for specialized error handling * **Validation exceptions** for field and document validation Exception Hierarchy -------------------- All QuantumEngine exceptions inherit from the base ``QuantumEngineException`` class: .. code-block:: python QuantumEngineException ├── ValidationError │ ├── FieldValidationError │ └── DocumentValidationError ├── DatabaseError │ ├── ConnectionError │ ├── QueryError │ └── TransactionError ├── BackendError │ ├── SurrealDBError │ └── ClickHouseError ├── DocumentError │ ├── DoesNotExist │ ├── MultipleObjectsReturned │ └── DocumentIntegrityError └── ConfigurationError ├── BackendConfigurationError └── FieldConfigurationError Core Exceptions --------------- Base Exception ~~~~~~~~~~~~~~ .. code-block:: python from quantumengine.exceptions import QuantumEngineException try: # QuantumEngine operation pass except QuantumEngineException as e: print(f"QuantumEngine error: {e}") ValidationError ~~~~~~~~~~~~~~~ Raised when data validation fails: .. code-block:: python from quantumengine.exceptions import ValidationError from quantumengine import Document from quantumengine.fields import StringField, IntField class User(Document): name = StringField(required=True) age = IntField(min_value=0, max_value=150) try: user = User(name="", age=-5) # Invalid data user.save() except ValidationError as e: print(f"Validation failed: {e}") print(f"Field errors: {e.field_errors}") DatabaseError ~~~~~~~~~~~~~ Raised for database-related errors: .. code-block:: python from quantumengine.exceptions import DatabaseError try: users = User.objects.all() except DatabaseError as e: print(f"Database error: {e}") print(f"Error code: {e.code}") print(f"Backend: {e.backend}") Field Validation Exceptions ---------------------------- FieldValidationError ~~~~~~~~~~~~~~~~~~~~ Raised when individual field validation fails: .. code-block:: python from quantumengine.exceptions import FieldValidationError from quantumengine.fields import EmailField try: email_field = EmailField() email_field.validate("invalid-email") except FieldValidationError as e: print(f"Field validation error: {e}") print(f"Field name: {e.field_name}") print(f"Invalid value: {e.value}") Common field validation errors: .. code-block:: python from quantumengine.fields import StringField, IntField, EmailField # Required field validation try: name_field = StringField(required=True) name_field.validate(None) except FieldValidationError as e: print("Required field is missing") # Range validation try: age_field = IntField(min_value=0, max_value=150) age_field.validate(200) except FieldValidationError as e: print("Value out of range") # Format validation try: email_field = EmailField() email_field.validate("not-an-email") except FieldValidationError as e: print("Invalid email format") Document Validation Exceptions ------------------------------- DocumentValidationError ~~~~~~~~~~~~~~~~~~~~~~~ Raised when document-level validation fails: .. code-block:: python from quantumengine.exceptions import DocumentValidationError class User(Document): username = StringField(required=True, unique=True) email = EmailField(required=True) def clean(self): # Custom validation if self.username.lower() == 'admin': raise DocumentValidationError("Username 'admin' is reserved") try: user = User(username='admin', email='admin@example.com') user.save() except DocumentValidationError as e: print(f"Document validation error: {e}") Database Operation Exceptions ------------------------------ DoesNotExist ~~~~~~~~~~~~ Raised when querying for a non-existent object: .. code-block:: python from quantumengine.exceptions import DoesNotExist try: user = User.objects.get(username='nonexistent') except DoesNotExist: print("User does not exist") # Each document class has its own DoesNotExist exception try: user = User.objects.get(username='nonexistent') except User.DoesNotExist: print("User does not exist") MultipleObjectsReturned ~~~~~~~~~~~~~~~~~~~~~~~ Raised when ``get()`` returns multiple objects: .. code-block:: python from quantumengine.exceptions import MultipleObjectsReturned try: user = User.objects.get(age=25) # Multiple users with age 25 except MultipleObjectsReturned: print("Multiple users found") # Safe alternative user = User.objects.filter(age=25).first() Connection Exceptions --------------------- ConnectionError ~~~~~~~~~~~~~~~ Raised when database connection fails: .. code-block:: python from quantumengine.exceptions import ConnectionError try: User.objects.all() except ConnectionError as e: print(f"Connection failed: {e}") print(f"Backend: {e.backend}") print(f"Connection details: {e.connection_info}") Query Exceptions ---------------- QueryError ~~~~~~~~~~ Raised when query execution fails: .. code-block:: python from quantumengine.exceptions import QueryError try: # Invalid query User.objects.filter(invalid_field='value') except QueryError as e: print(f"Query error: {e}") print(f"Query: {e.query}") print(f"Parameters: {e.params}") Backend-Specific Exceptions --------------------------- SurrealDBError ~~~~~~~~~~~~~~ Specific to SurrealDB backend operations: .. code-block:: python from quantumengine.exceptions import SurrealDBError try: # SurrealDB-specific operation User.objects.raw("INVALID SURREALQL") except SurrealDBError as e: print(f"SurrealDB error: {e}") print(f"Error code: {e.surrealdb_code}") print(f"Details: {e.details}") ClickHouseError ~~~~~~~~~~~~~~~ Specific to ClickHouse backend operations: .. code-block:: python from quantumengine.exceptions import ClickHouseError try: # ClickHouse-specific operation Analytics.objects.raw("INVALID SQL") except ClickHouseError as e: print(f"ClickHouse error: {e}") print(f"Error code: {e.clickhouse_code}") print(f"Query: {e.query}") Configuration Exceptions ------------------------ BackendConfigurationError ~~~~~~~~~~~~~~~~~~~~~~~~~ Raised when backend configuration is invalid: .. code-block:: python from quantumengine.exceptions import BackendConfigurationError from quantumengine import configure_backend try: configure_backend('surrealdb', { 'url': 'invalid-url', 'namespace': '', # Invalid empty namespace }) except BackendConfigurationError as e: print(f"Configuration error: {e}") print(f"Backend: {e.backend}") print(f"Invalid config: {e.config}") Transaction Exceptions ---------------------- TransactionError ~~~~~~~~~~~~~~~~ Raised when transaction operations fail: .. code-block:: python from quantumengine.exceptions import TransactionError from quantumengine import transaction try: with transaction.atomic(): user = User.objects.create(name='John') # Simulate error raise Exception("Something went wrong") except TransactionError as e: print(f"Transaction error: {e}") print(f"Transaction ID: {e.transaction_id}") Error Handling Best Practices ------------------------------ Specific Exception Handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Catch specific exceptions rather than generic ones: .. code-block:: python from quantumengine.exceptions import DoesNotExist, ValidationError def get_user_safely(username): try: return User.objects.get(username=username) except DoesNotExist: return None except ValidationError as e: logger.error(f"Validation error for username {username}: {e}") return None Logging Exceptions ~~~~~~~~~~~~~~~~~~ Log exceptions with context for debugging: .. code-block:: python import logging from quantumengine.exceptions import DatabaseError logger = logging.getLogger(__name__) def handle_database_error(func): def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except DatabaseError as e: logger.error(f"Database error in {func.__name__}: {e}", extra={ 'backend': e.backend, 'error_code': e.code, 'function': func.__name__, 'args': args, 'kwargs': kwargs }) raise return wrapper @handle_database_error def get_user_by_id(user_id): return User.objects.get(id=user_id) Graceful Degradation ~~~~~~~~~~~~~~~~~~~~ Handle exceptions gracefully in production: .. code-block:: python from quantumengine.exceptions import ConnectionError, QueryError def get_user_with_fallback(username): try: return User.objects.get(username=username) except ConnectionError: # Fallback to cache or return default return get_user_from_cache(username) except QueryError: # Log error and return safe default logger.warning(f"Query error for username: {username}") return create_anonymous_user() Custom Exceptions ----------------- Create application-specific exceptions: .. code-block:: python from quantumengine.exceptions import QuantumEngineException class UserNotActiveError(QuantumEngineException): """Raised when trying to perform operations on inactive user""" pass class InsufficientPermissionsError(QuantumEngineException): """Raised when user lacks required permissions""" pass def activate_user(user_id): try: user = User.objects.get(id=user_id) if not user.is_active: raise UserNotActiveError(f"User {user_id} is not active") return user except DoesNotExist: raise UserNotActiveError(f"User {user_id} does not exist") Exception Context ----------------- Exceptions provide context for debugging: .. code-block:: python from quantumengine.exceptions import QueryError try: User.objects.filter(age__invalid_lookup=25) except QueryError as e: print(f"Error: {e}") print(f"Query: {e.query}") print(f"Backend: {e.backend}") print(f"Traceback: {e.traceback}") Testing Exceptions ------------------ Test exception handling in your code: .. code-block:: python import pytest from quantumengine.exceptions import DoesNotExist, ValidationError def test_user_not_found(): with pytest.raises(DoesNotExist): User.objects.get(username='nonexistent') def test_validation_error(): with pytest.raises(ValidationError) as exc_info: user = User(name='', age=-5) user.save() assert 'name' in exc_info.value.field_errors assert 'age' in exc_info.value.field_errors Exception Middleware -------------------- Handle exceptions at the application level: .. code-block:: python from quantumengine.exceptions import QuantumEngineException class QuantumEngineExceptionMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): try: response = self.get_response(request) return response except QuantumEngineException as e: # Log and handle QuantumEngine exceptions logger.error(f"QuantumEngine error: {e}") return handle_quantumengine_error(e) See Also -------- * :doc:`/api/exceptions` - Complete exceptions API reference * :doc:`/fields/index` - Field validation and exceptions * :doc:`/query/index` - Query exceptions and error handling * :doc:`/backends/index` - Backend-specific exception handling