MukeshKapoor25's picture
Initial commit: Booking Allocation Engine with complete documentation
7f9f4b4
"""
Custom exception classes for the Booking Allocation Engine.
This module defines the exception hierarchy used throughout the allocation system
to distinguish between transient errors (retryable) and permanent errors (non-retryable).
"""
class AllocationError(Exception):
"""Base exception for all allocation-related errors."""
def __init__(self, message: str, booking_id: str = None, partner_id: str = None):
self.message = message
self.booking_id = booking_id
self.partner_id = partner_id
super().__init__(self.message)
class TransientError(AllocationError):
"""
Transient errors that may succeed on retry.
These errors indicate temporary failures such as network issues,
database connection problems, or service unavailability.
Operations that raise TransientError should be retried with backoff.
"""
pass
class PermanentError(AllocationError):
"""
Permanent errors that will not succeed on retry.
These errors indicate business logic violations, validation failures,
or data integrity issues that cannot be resolved by retrying.
Operations that raise PermanentError should not be retried.
"""
pass
class DatabaseConnectionError(TransientError):
"""
Database connection or query execution failure.
Raised when PostgreSQL connection fails or times out.
Should be retried with exponential backoff.
"""
def __init__(self, message: str, operation: str = None, booking_id: str = None):
self.operation = operation
super().__init__(message, booking_id=booking_id)
class RedisError(TransientError):
"""
Redis connection or operation failure.
Raised when Redis connection fails or times out.
Should trigger fallback to PostgreSQL for data retrieval.
"""
def __init__(self, message: str, key: str = None, operation: str = None):
self.key = key
self.operation = operation
super().__init__(message)
class NoEligiblePartnersError(PermanentError):
"""
No eligible partners found for booking.
Raised when partner filtering returns empty result set.
Should set allocation_status to 'failed'.
"""
pass
class BookingAlreadyAssignedError(PermanentError):
"""
Booking already assigned to a partner.
Raised when attempting to create offer for already-assigned booking.
Should abort allocation attempt.
"""
pass
class InvalidEventStructureError(PermanentError):
"""
Event structure validation failed.
Raised when required fields are missing or have invalid types.
Event should be discarded and logged.
"""
def __init__(self, message: str, event_data: dict = None):
self.event_data = event_data
super().__init__(message)
class OfferExpiredError(PermanentError):
"""
Offer has already expired.
Raised when partner responds after offer expiry timeout.
Response should be rejected.
"""
def __init__(self, message: str, offer_id: str = None, expiry_time: str = None):
self.offer_id = offer_id
self.expiry_time = expiry_time
super().__init__(message)
class DuplicateResponseError(PermanentError):
"""
Partner already responded to offer.
Raised when duplicate accept/decline response received.
Duplicate response should be ignored.
"""
def __init__(self, message: str, offer_id: str = None, previous_response: str = None):
self.offer_id = offer_id
self.previous_response = previous_response
super().__init__(message)