Coverage for utils/custom_exception.py: 94.23%

52 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2026-01-25 13:05 +0000

1import logging 

2from typing import Optional, Dict, Any 

3 

4logger = logging.getLogger(__name__) 

5 

6class BaseServiceException(Exception): 

7 def __init__( 

8 self, 

9 message: str, 

10 error_code: str = None, 

11 details: Optional[Dict[str, Any]] = None, 

12 status_code: int = None, 

13 log_level: str = None 

14 ): 

15 self.message = message 

16 self.error_code = error_code 

17 self.details = details or {} 

18 if status_code is not None: 

19 self.status_code = status_code 

20 if log_level is not None: 

21 self.log_level = log_level 

22 

23 log_msg = f"[{self.error_code}] | {self.message}" 

24 

25 if self.log_level == "error": 

26 logger.error(log_msg) 

27 elif self.log_level == "warning": 

28 logger.warning(log_msg) 

29 else: 

30 logger.info(log_msg) 

31 super().__init__(self.message) 

32 

33class ServerException(BaseServiceException): 

34 """Server exception""" 

35 def __init__(self, message: str = "Server error", status_code: int = 500, details: Dict[str, Any] = None): 

36 super().__init__(message=message, error_code="SERVER_ERROR", details=details, status_code=status_code, log_level="error") 

37 

38class AuthenticationException(BaseServiceException): 

39 """Authentication related exceptions""" 

40 def __init__(self, message: str = "Authentication failed", details: Dict[str, Any] = None): 

41 super().__init__(message=message, error_code="AUTH_ERROR", details=details, status_code=401, log_level="warning") 

42 

43class PasswordResetRequiredException(BaseServiceException): 

44 """Password reset required exception""" 

45 def __init__(self, message: str = "Password reset required", details: Dict[str, Any] = None): 

46 super().__init__(message=message, error_code="PASSWORD_RESET_REQUIRED", details=details, status_code=202, log_level="warning") 

47 

48class EmailVerificationRequiredException(BaseServiceException): 

49 """Email verification required exception""" 

50 def __init__(self, message: str = "Email verification required", details: Dict[str, Any] = None): 

51 super().__init__(message=message, error_code="EMAIL_VERIFICATION_REQUIRED", details=details, status_code=202, log_level="warning") 

52 

53class AuthorizationException(BaseServiceException): 

54 """Authorization related exceptions""" 

55 def __init__(self, message: str = "Permission denied", details: Dict[str, Any] = None): 

56 super().__init__(message=message, error_code="PERMISSION_ERROR", details=details, status_code=403, log_level="warning") 

57 

58class ValidationException(BaseServiceException): 

59 """Validation related exceptions""" 

60 def __init__(self, message: str = "Validation failed", details: Dict[str, Any] = None): 

61 super().__init__(message=message, error_code="VALIDATION_ERROR", details=details, status_code=400, log_level="warning") 

62 

63class NotFoundException(BaseServiceException): 

64 """Resource not found exceptions""" 

65 def __init__(self, message: str = "Resource not found", details: Dict[str, Any] = None): 

66 super().__init__(message=message, error_code="NOT_FOUND", details=details, status_code=404, log_level="warning") 

67 

68class ConflictException(BaseServiceException): 

69 """Resource conflict exceptions""" 

70 def __init__(self, message: str = "Resource conflict", details: Dict[str, Any] = None): 

71 super().__init__(message=message, error_code="CONFLICT", details=details, status_code=409, log_level="warning") 

72 

73class TokenException(BaseServiceException): 

74 """Token related exceptions""" 

75 def __init__(self, message: str = "Token error", details: Dict[str, Any] = None): 

76 super().__init__(message=message, error_code="TOKEN_ERROR", details=details, status_code=401, log_level="warning") 

77 

78class SMTPNotConfiguredException(BaseServiceException): 

79 """SMTP configuration related exceptions""" 

80 def __init__(self, message: str = "SMTP is not configured", details: Dict[str, Any] = None): 

81 super().__init__(message=message, error_code="SMTP_NOT_CONFIGURED", details=details, status_code=503, log_level="warning") 

82 

83class RegistrationDisabledException(BaseServiceException): 

84 """Registration disabled exception""" 

85 def __init__(self, message: str = "Registration is disabled", details: Dict[str, Any] = None): 

86 super().__init__(message=message, error_code="REGISTRATION_DISABLED", details=details, status_code=503, log_level="warning")