mitlist/be/app/core/exceptions.py
2025-05-07 20:16:16 +02:00

210 lines
7.6 KiB
Python

from fastapi import HTTPException, status
class ListNotFoundError(HTTPException):
"""Raised when a list is not found."""
def __init__(self, list_id: int):
super().__init__(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"List {list_id} not found"
)
class ListPermissionError(HTTPException):
"""Raised when a user doesn't have permission to access a list."""
def __init__(self, list_id: int, action: str = "access"):
super().__init__(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"You do not have permission to {action} list {list_id}"
)
class ListCreatorRequiredError(HTTPException):
"""Raised when an action requires the list creator but the user is not the creator."""
def __init__(self, list_id: int, action: str):
super().__init__(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"Only the list creator can {action} list {list_id}"
)
class GroupNotFoundError(HTTPException):
"""Raised when a group is not found."""
def __init__(self, group_id: int):
super().__init__(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Group {group_id} not found"
)
class GroupPermissionError(HTTPException):
"""Raised when a user doesn't have permission to perform an action in a group."""
def __init__(self, group_id: int, action: str):
super().__init__(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"You do not have permission to {action} in group {group_id}"
)
class GroupMembershipError(HTTPException):
"""Raised when a user attempts to perform an action that requires group membership."""
def __init__(self, group_id: int, action: str = "access"):
super().__init__(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"You must be a member of group {group_id} to {action}"
)
class GroupOperationError(HTTPException):
"""Raised when a group operation fails."""
def __init__(self, detail: str):
super().__init__(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=detail
)
class GroupValidationError(HTTPException):
"""Raised when a group operation is invalid."""
def __init__(self, detail: str):
super().__init__(
status_code=status.HTTP_400_BAD_REQUEST,
detail=detail
)
class ItemNotFoundError(HTTPException):
"""Raised when an item is not found."""
def __init__(self, item_id: int):
super().__init__(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Item {item_id} not found"
)
class DatabaseConnectionError(HTTPException):
"""Raised when there is an error connecting to the database."""
def __init__(self, detail: str = "Database connection error"):
super().__init__(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail=detail
)
class DatabaseIntegrityError(HTTPException):
"""Raised when a database integrity constraint is violated."""
def __init__(self, detail: str = "Database integrity error"):
super().__init__(
status_code=status.HTTP_400_BAD_REQUEST,
detail=detail
)
class DatabaseTransactionError(HTTPException):
"""Raised when a database transaction fails."""
def __init__(self, detail: str = "Database transaction error"):
super().__init__(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=detail
)
class DatabaseQueryError(HTTPException):
"""Raised when a database query fails."""
def __init__(self, detail: str = "Database query error"):
super().__init__(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=detail
)
class OcrServiceUnavailableError(HTTPException):
"""Raised when the OCR service is unavailable."""
def __init__(self, detail: str):
super().__init__(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail=f"OCR service unavailable: {detail}"
)
class InvalidFileTypeError(HTTPException):
"""Raised when an invalid file type is uploaded for OCR."""
def __init__(self, allowed_types: list[str]):
super().__init__(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Invalid file type. Allowed types: {', '.join(allowed_types)}"
)
class FileTooLargeError(HTTPException):
"""Raised when an uploaded file exceeds the size limit."""
def __init__(self, max_size_mb: int):
super().__init__(
status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
detail=f"File size exceeds limit of {max_size_mb} MB."
)
class OcrProcessingError(HTTPException):
"""Raised when there is an error processing the image with OCR."""
def __init__(self, detail: str):
super().__init__(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=f"Could not extract items from image: {detail}"
)
class OcrQuotaExceededError(HTTPException):
"""Raised when the OCR service quota is exceeded."""
def __init__(self):
super().__init__(
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
detail="OCR service quota exceeded. Please try again later."
)
class EmailAlreadyRegisteredError(HTTPException):
"""Raised when attempting to register with an email that is already in use."""
def __init__(self):
super().__init__(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Email already registered."
)
class InvalidCredentialsError(HTTPException):
"""Raised when login credentials are invalid."""
def __init__(self):
super().__init__(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect email or password",
headers={"WWW-Authenticate": "Bearer"}
)
class UserCreationError(HTTPException):
"""Raised when there is an error creating a new user."""
def __init__(self):
super().__init__(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="An error occurred during user creation."
)
class InviteNotFoundError(HTTPException):
"""Raised when an invite is not found."""
def __init__(self, invite_code: str):
super().__init__(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Invite code {invite_code} not found"
)
class InviteExpiredError(HTTPException):
"""Raised when an invite has expired."""
def __init__(self, invite_code: str):
super().__init__(
status_code=status.HTTP_410_GONE,
detail=f"Invite code {invite_code} has expired"
)
class InviteAlreadyUsedError(HTTPException):
"""Raised when an invite has already been used."""
def __init__(self, invite_code: str):
super().__init__(
status_code=status.HTTP_410_GONE,
detail=f"Invite code {invite_code} has already been used"
)
class InviteCreationError(HTTPException):
"""Raised when an invite cannot be created."""
def __init__(self, group_id: int):
super().__init__(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to create invite for group {group_id}"
)
class ListStatusNotFoundError(HTTPException):
"""Raised when a list's status cannot be retrieved."""
def __init__(self, list_id: int):
super().__init__(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Status for list {list_id} not found"
)