"""Application exception hierarchy.

All custom exceptions inherit from AppError. The global exception handler
in middleware.py catches these and returns the appropriate JSON envelope.
"""


class AppError(Exception):
    """Base application error."""

    status_code: int = 500
    message: str = "Internal server error"

    def __init__(self, message: str | None = None):
        if message is not None:
            self.message = message
        super().__init__(self.message)


class ValidationError(AppError):
    status_code = 400
    message = "Validation error"


class NotFoundError(AppError):
    status_code = 404
    message = "Resource not found"


class DuplicateError(AppError):
    status_code = 409
    message = "Resource already exists"


class AuthenticationError(AppError):
    status_code = 401
    message = "Authentication required"


class AuthorizationError(AppError):
    status_code = 403
    message = "Insufficient permissions"


class ProviderError(AppError):
    status_code = 502
    message = "Market data provider unavailable"


class RateLimitError(AppError):
    status_code = 429
    message = "Rate limited"
