Files
routesapi/app/core/exceptions.py

71 lines
1.9 KiB
Python

"""Custom exceptions for the API."""
from fastapi import HTTPException, status
class APIException(HTTPException):
"""Base API exception with structured error format."""
def __init__(
self,
status_code: int,
message: str,
field: str = None,
code: str = None,
detail: str = None
):
self.message = message
self.field = field
self.code = code or self._get_default_code(status_code)
super().__init__(status_code=status_code, detail=detail or message)
def _get_default_code(self, status_code: int) -> str:
"""Get default error code based on status code."""
codes = {
400: "BAD_REQUEST",
401: "UNAUTHORIZED",
403: "FORBIDDEN",
404: "NOT_FOUND",
409: "CONFLICT",
422: "VALIDATION_ERROR",
429: "RATE_LIMIT_EXCEEDED",
500: "INTERNAL_SERVER_ERROR",
503: "SERVICE_UNAVAILABLE"
}
return codes.get(status_code, "UNKNOWN_ERROR")
class ValidationError(APIException):
"""Validation error exception."""
def __init__(self, message: str, field: str = None):
super().__init__(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
message=message,
field=field,
code="VALIDATION_ERROR"
)
class NotFoundError(APIException):
"""Resource not found exception."""
def __init__(self, message: str = "Resource not found"):
super().__init__(
status_code=status.HTTP_404_NOT_FOUND,
message=message,
code="NOT_FOUND"
)
class RateLimitError(APIException):
"""Rate limit exceeded exception."""
def __init__(self, message: str = "Rate limit exceeded"):
super().__init__(
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
message=message,
code="RATE_LIMIT_EXCEEDED"
)