Files
ebook-extension/ebook_backend_admin_panel/admin-backend/utils/exceptions.py
richardtekula f78c2199e1 Fix: Rename directory to remove & character causing shell issues
Renamed ebook_backend&admin_panel to ebook_backend_admin_panel
  The & character was being interpreted by shell as background
  process operator, causing 'Dockerfile not found' errors in Coolify.
2025-11-11 17:06:39 +01:00

211 lines
5.4 KiB
Python

"""
Custom exceptions for the Ebook Coupon Management System
Provides structured error handling with proper error codes and messages.
"""
from typing import Dict, Any, Optional
from fastapi import HTTPException
class APIException(HTTPException):
"""Base API exception with structured error information"""
def __init__(
self,
status_code: int,
detail: str,
error_code: str,
extra_data: Optional[Dict[str, Any]] = None
):
super().__init__(status_code=status_code, detail=detail)
self.error_code = error_code
self.extra_data = extra_data or {}
class AuthenticationError(APIException):
"""Authentication related errors"""
def __init__(self, detail: str = "Authentication failed"):
super().__init__(
status_code=401,
detail=detail,
error_code="AUTHENTICATION_ERROR"
)
class AuthorizationError(APIException):
"""Authorization related errors"""
def __init__(self, detail: str = "Access denied"):
super().__init__(
status_code=403,
detail=detail,
error_code="AUTHORIZATION_ERROR"
)
class NotFoundError(APIException):
"""Resource not found errors"""
def __init__(self, resource: str, detail: Optional[str] = None):
if detail is None:
detail = f"{resource} not found"
super().__init__(
status_code=404,
detail=detail,
error_code="NOT_FOUND_ERROR"
)
class ValidationError(APIException):
"""Validation related errors"""
def __init__(self, detail: str, field: Optional[str] = None):
if field:
detail = f"Validation error in field '{field}': {detail}"
super().__init__(
status_code=422,
detail=detail,
error_code="VALIDATION_ERROR"
)
class ConflictError(APIException):
"""Resource conflict errors"""
def __init__(self, detail: str):
super().__init__(
status_code=409,
detail=detail,
error_code="CONFLICT_ERROR"
)
class RateLimitError(APIException):
"""Rate limiting errors"""
def __init__(self, detail: str = "Rate limit exceeded"):
super().__init__(
status_code=429,
detail=detail,
error_code="RATE_LIMIT_ERROR"
)
class DatabaseError(APIException):
"""Database related errors"""
def __init__(self, detail: str = "Database operation failed"):
super().__init__(
status_code=500,
detail=detail,
error_code="DATABASE_ERROR"
)
class FileUploadError(APIException):
"""File upload related errors"""
def __init__(self, detail: str):
super().__init__(
status_code=400,
detail=detail,
error_code="FILE_UPLOAD_ERROR"
)
class CouponError(APIException):
"""Coupon related errors"""
def __init__(self, detail: str, error_code: str = "COUPON_ERROR"):
super().__init__(
status_code=400,
detail=detail,
error_code=error_code
)
def handle_api_exception(exc: APIException, path: str) -> Dict[str, Any]:
"""
Handle API exception and return structured error response
Args:
exc: API exception instance
path: Request path
Returns:
Structured error response
"""
return {
"success": False,
"error": exc.detail,
"error_code": exc.error_code,
"timestamp": None, # Will be set by exception handler
"path": path,
**exc.extra_data
}
# Coupon specific exceptions
class CouponNotFoundError(NotFoundError):
"""Coupon not found error"""
def __init__(self, code: str):
super().__init__("coupon", f"Coupon code '{code}' not found")
class CouponAlreadyUsedError(CouponError):
"""Coupon already used error"""
def __init__(self, code: str):
super().__init__(
f"Coupon code '{code}' has already been used",
"COUPON_ALREADY_USED"
)
class CouponBlockedError(CouponError):
"""Coupon blocked error"""
def __init__(self, code: str, remaining_minutes: int):
super().__init__(
f"Coupon code '{code}' is blocked. Try again in {remaining_minutes} minutes",
"COUPON_BLOCKED"
)
class CouponLimitExceededError(CouponError):
"""Coupon usage limit exceeded error"""
def __init__(self, code: str, limit: int):
super().__init__(
f"Coupon code '{code}' usage limit ({limit}) exceeded",
"COUPON_LIMIT_EXCEEDED"
)
# File upload specific exceptions
class FileTypeError(FileUploadError):
"""Invalid file type error"""
def __init__(self, allowed_types: list):
super().__init__(
f"Invalid file type. Allowed types: {', '.join(allowed_types)}"
)
class FileSizeError(FileUploadError):
"""File too large error"""
def __init__(self, max_size_mb: int):
super().__init__(
f"File too large. Maximum size: {max_size_mb}MB"
)
class FileExistsError(FileUploadError):
"""File already exists error"""
def __init__(self, filename: str):
super().__init__(
f"File '{filename}' already exists. Please delete it first."
)