53 lines
1.1 KiB
Python
53 lines
1.1 KiB
Python
"""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"
|