# app/exceptions/product.py """ Product (vendor catalog) specific exceptions. """ from .base import ( BusinessLogicException, ConflictException, ResourceNotFoundException, ValidationException, ) class ProductNotFoundException(ResourceNotFoundException): """Raised when a product is not found in vendor catalog.""" def __init__(self, product_id: int, vendor_id: int | None = None): if vendor_id: message = f"Product with ID '{product_id}' not found in vendor {vendor_id} catalog" else: message = f"Product with ID '{product_id}' not found" super().__init__( resource_type="Product", identifier=str(product_id), message=message, error_code="PRODUCT_NOT_FOUND", ) # Add extra details after init self.details["product_id"] = product_id if vendor_id: self.details["vendor_id"] = vendor_id class ProductAlreadyExistsException(ConflictException): """Raised when trying to add a marketplace product that's already in vendor catalog.""" def __init__(self, vendor_id: int, marketplace_product_id: int): super().__init__( message=f"Marketplace product {marketplace_product_id} already exists in vendor {vendor_id} catalog", error_code="PRODUCT_ALREADY_EXISTS", details={ "vendor_id": vendor_id, "marketplace_product_id": marketplace_product_id, }, ) class ProductNotInCatalogException(ResourceNotFoundException): """Raised when trying to access a product that's not in vendor's catalog.""" def __init__(self, product_id: int, vendor_id: int): super().__init__( resource_type="Product", identifier=str(product_id), message=f"Product {product_id} is not in vendor {vendor_id} catalog", error_code="PRODUCT_NOT_IN_CATALOG", details={ "product_id": product_id, "vendor_id": vendor_id, }, ) class ProductNotActiveException(BusinessLogicException): """Raised when trying to perform operations on inactive product.""" def __init__(self, product_id: int, vendor_id: int): super().__init__( message=f"Product {product_id} in vendor {vendor_id} catalog is not active", error_code="PRODUCT_NOT_ACTIVE", details={ "product_id": product_id, "vendor_id": vendor_id, }, ) class InvalidProductDataException(ValidationException): """Raised when product data is invalid.""" def __init__( self, message: str = "Invalid product data", field: str | None = None, details: dict | None = None, ): super().__init__( message=message, field=field, details=details, ) self.error_code = "INVALID_PRODUCT_DATA" class ProductValidationException(ValidationException): """Raised when product validation fails.""" def __init__( self, message: str = "Product validation failed", field: str | None = None, validation_errors: dict | None = None, ): details = {} if validation_errors: details["validation_errors"] = validation_errors super().__init__( message=message, field=field, details=details, ) self.error_code = "PRODUCT_VALIDATION_FAILED" class CannotDeleteProductWithInventoryException(BusinessLogicException): """Raised when trying to delete a product that has inventory.""" def __init__(self, product_id: int, inventory_count: int): super().__init__( message=f"Cannot delete product {product_id} - it has {inventory_count} inventory entries", error_code="CANNOT_DELETE_PRODUCT_WITH_INVENTORY", details={ "product_id": product_id, "inventory_count": inventory_count, }, ) class CannotDeleteProductWithOrdersException(BusinessLogicException): """Raised when trying to delete a product that has been ordered.""" def __init__(self, product_id: int, order_count: int): super().__init__( message=f"Cannot delete product {product_id} - it has {order_count} associated orders", error_code="CANNOT_DELETE_PRODUCT_WITH_ORDERS", details={ "product_id": product_id, "order_count": order_count, }, )