Coverage for /home/runner/work/bijux-cli/bijux-cli/src/bijux_cli/core/exceptions.py: 100%

22 statements  

« prev     ^ index     » next       coverage.py v7.10.4, created at 2025-08-19 23:36 +0000

1# SPDX-License-Identifier: MIT 

2# Copyright © 2025 Bijan Mousavi 

3 

4"""Defines the custom exception hierarchy for the Bijux CLI. 

5 

6This module provides a set of custom exception classes that inherit from the 

7base `BijuxError`. This hierarchy allows for more specific error handling 

8and helps standardize error reporting throughout the application. Each 

9exception can carry contextual information, such as the command that was 

10running when the error occurred. 

11""" 

12 

13from __future__ import annotations 

14 

15 

16class BijuxError(Exception): 

17 """Base exception for all custom errors in the Bijux CLI. 

18 

19 Attributes: 

20 command (str | None): The name of the command being executed when 

21 the error occurred. 

22 http_status (int): An HTTP-like status code used to derive the 

23 final CLI exit code. 

24 

25 Args: 

26 message (str): The human-readable error message. 

27 command (str | None): The name of the command. 

28 http_status (int | None): The associated status code. 

29 """ 

30 

31 def __init__( 

32 self, 

33 message: str, 

34 *, 

35 command: str | None = None, 

36 http_status: int | None = None, 

37 ) -> None: 

38 """Initialize the base BijuxError exception.""" 

39 self.command = command 

40 self.http_status = http_status if http_status is not None else 500 

41 super().__init__(message) 

42 

43 

44class ServiceError(BijuxError): 

45 """Raised for service-related failures. 

46 

47 This exception is used for errors originating from core services like 

48 Observability, Telemetry, or the Registry. 

49 

50 Args: 

51 message (str): The human-readable error message. 

52 command (str | None): The name of the command. 

53 http_status (int | None): The associated status code. Defaults to 500. 

54 """ 

55 

56 def __init__( 

57 self, 

58 message: str, 

59 *, 

60 command: str | None = None, 

61 http_status: int | None = None, 

62 ) -> None: 

63 """Initialize the ServiceError exception.""" 

64 super().__init__( 

65 message, 

66 command=command, 

67 http_status=http_status if http_status is not None else 500, 

68 ) 

69 

70 

71class CommandError(BijuxError): 

72 """Raised for command execution failures. 

73 

74 This exception is used for command-specific errors, such as invalid 

75 arguments or missing resources, that represent a client-side error. 

76 

77 Args: 

78 message (str): The human-readable error message. 

79 command (str | None): The name of the command. 

80 http_status (int | None): The associated status code. Defaults to 400. 

81 """ 

82 

83 def __init__( 

84 self, 

85 message: str, 

86 *, 

87 command: str | None = None, 

88 http_status: int | None = None, 

89 ) -> None: 

90 """Initialize the CommandError exception.""" 

91 super().__init__( 

92 message, 

93 command=command, 

94 http_status=http_status if http_status is not None else 400, 

95 ) 

96 

97 

98class ConfigError(BijuxError): 

99 """Raised for configuration loading or parsing failures. 

100 

101 Args: 

102 message (str): The human-readable error message. 

103 command (str | None): The name of the command. 

104 http_status (int | None): The associated status code. Defaults to 400. 

105 """ 

106 

107 def __init__( 

108 self, 

109 message: str, 

110 *, 

111 command: str | None = None, 

112 http_status: int | None = None, 

113 ) -> None: 

114 """Initialize the ConfigError exception.""" 

115 super().__init__( 

116 message, 

117 command=command, 

118 http_status=http_status if http_status is not None else 400, 

119 ) 

120 

121 

122class ValidationError(BijuxError): 

123 """Raised for validation failures (deprecated). 

124 

125 Note: 

126 This exception is deprecated. Use `CommandError` for new code. 

127 

128 Args: 

129 message (str): The human-readable error message. 

130 command (str | None): The name of the command. 

131 http_status (int | None): The associated status code. Defaults to 400. 

132 """ 

133 

134 def __init__( 

135 self, 

136 message: str, 

137 *, 

138 command: str | None = None, 

139 http_status: int | None = None, 

140 ) -> None: 

141 """Initialize the ValidationError exception.""" 

142 super().__init__( 

143 message, 

144 command=command, 

145 http_status=http_status if http_status is not None else 400, 

146 ) 

147 

148 

149class CliTimeoutError(BijuxError): 

150 """Raised for timeout errors (deprecated). 

151 

152 Note: 

153 This exception is deprecated. Use `CommandError` or Python's built-in 

154 `TimeoutError` for new code. 

155 

156 Args: 

157 message (str): The human-readable error message. 

158 command (str | None): The name of the command. 

159 http_status (int | None): The associated status code. Defaults to 504. 

160 """ 

161 

162 def __init__( 

163 self, 

164 message: str, 

165 *, 

166 command: str | None = None, 

167 http_status: int | None = None, 

168 ) -> None: 

169 """Initialize the CliTimeoutError exception.""" 

170 super().__init__( 

171 message, 

172 command=command, 

173 http_status=http_status if http_status is not None else 504, 

174 ) 

175 

176 

177__all__ = [ 

178 "BijuxError", 

179 "ServiceError", 

180 "CommandError", 

181 "ConfigError", 

182 "ValidationError", 

183 "CliTimeoutError", 

184]