Coverage for utils/custom_exception.py: 94.12%
51 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-09-03 15:30 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-09-03 15:30 +0000
1import logging
2from typing import Any
4logger = logging.getLogger("exception")
7class BaseServiceException(Exception):
8 def __init__(
9 self,
10 message: str,
11 error_code: str = None,
12 details: dict[str, Any] | None = None,
13 status_code: int = None,
14 log_level: str = None,
15 ):
16 self.message = message
17 self.error_code = error_code
18 self.details = details or {}
19 self.log_level = log_level
20 if status_code is not None:
21 self.status_code = status_code
23 if self.log_level == "error":
24 logger.error(self.message)
25 elif self.log_level == "warning":
26 logger.warning(self.message)
27 elif self.log_level == "info":
28 logger.info(self.message)
30 super().__init__(self.message)
33class ServerException(BaseServiceException):
34 """Server exception"""
36 def __init__(
37 self, message: str = "Server error", status_code: int = 500, details: dict[str, Any] = None
38 ):
39 super().__init__(
40 message=message,
41 error_code="SERVER_ERROR",
42 details=details,
43 status_code=status_code,
44 log_level="error",
45 )
48class AuthenticationException(BaseServiceException):
49 """Authentication related exceptions"""
51 def __init__(self, message: str = "Authentication failed", details: dict[str, Any] = None):
52 super().__init__(message=message, error_code="AUTH_ERROR", details=details, status_code=401)
55class PasswordResetRequiredException(BaseServiceException):
56 """Password reset required exception"""
58 def __init__(self, message: str = "Password reset required", details: dict[str, Any] = None):
59 super().__init__(
60 message=message, error_code="PASSWORD_RESET_REQUIRED", details=details, status_code=202
61 )
64class EmailVerificationRequiredException(BaseServiceException):
65 """Email verification required exception"""
67 def __init__(
68 self, message: str = "Email verification required", details: dict[str, Any] = None
69 ):
70 super().__init__(
71 message=message,
72 error_code="EMAIL_VERIFICATION_REQUIRED",
73 details=details,
74 status_code=202,
75 )
78class AuthorizationException(BaseServiceException):
79 """Authorization related exceptions"""
81 def __init__(self, message: str = "Permission denied", details: dict[str, Any] = None):
82 super().__init__(
83 message=message, error_code="PERMISSION_ERROR", details=details, status_code=403
84 )
87class ValidationException(BaseServiceException):
88 """Validation related exceptions"""
90 def __init__(self, message: str = "Validation failed", details: dict[str, Any] = None):
91 super().__init__(
92 message=message, error_code="VALIDATION_ERROR", details=details, status_code=400
93 )
96class NotFoundException(BaseServiceException):
97 """Resource not found exceptions"""
99 def __init__(self, message: str = "Resource not found", details: dict[str, Any] = None):
100 super().__init__(message=message, error_code="NOT_FOUND", details=details, status_code=404)
103class ConflictException(BaseServiceException):
104 """Resource conflict exceptions"""
106 def __init__(self, message: str = "Resource conflict", details: dict[str, Any] = None):
107 super().__init__(message=message, error_code="CONFLICT", details=details, status_code=409)
110class TokenException(BaseServiceException):
111 """Token related exceptions"""
113 def __init__(self, message: str = "Token error", details: dict[str, Any] = None):
114 super().__init__(
115 message=message, error_code="TOKEN_ERROR", details=details, status_code=401
116 )
119class SMTPNotConfiguredException(BaseServiceException):
120 """SMTP configuration related exceptions"""
122 def __init__(self, message: str = "SMTP is not configured", details: dict[str, Any] = None):
123 super().__init__(
124 message=message, error_code="SMTP_NOT_CONFIGURED", details=details, status_code=503
125 )
128class RegistrationDisabledException(BaseServiceException):
129 """Registration disabled exception"""
131 def __init__(self, message: str = "Registration is disabled", details: dict[str, Any] = None):
132 super().__init__(
133 message=message, error_code="REGISTRATION_DISABLED", details=details, status_code=503
134 )