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

17 statements  

« prev     ^ index     » next       coverage.py v7.13.2, created at 2026-01-26 17:59 +0000

1# SPDX-License-Identifier: Apache-2.0 

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 UserInputError(BijuxError): 

45 """Raised for user input and validation failures.""" 

46 

47 def __init__( 

48 self, 

49 message: str, 

50 *, 

51 command: str | None = None, 

52 http_status: int | None = None, 

53 ) -> None: 

54 """Initialize a user input error.""" 

55 super().__init__( 

56 message, 

57 command=command, 

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

59 ) 

60 

61 

62class ConfigError(UserInputError): 

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

64 

65 

66class PluginError(BijuxError): 

67 """Raised for plugin lifecycle and compatibility failures.""" 

68 

69 def __init__( 

70 self, 

71 message: str, 

72 *, 

73 command: str | None = None, 

74 http_status: int | None = None, 

75 ) -> None: 

76 """Initialize a plugin error.""" 

77 super().__init__( 

78 message, 

79 command=command, 

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

81 ) 

82 

83 

84class InternalError(BijuxError): 

85 """Raised for internal failures.""" 

86 

87 def __init__( 

88 self, 

89 message: str, 

90 *, 

91 command: str | None = None, 

92 http_status: int | None = None, 

93 ) -> None: 

94 """Initialize an internal error.""" 

95 super().__init__( 

96 message, 

97 command=command, 

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

99 ) 

100 

101 

102__all__ = [ 

103 "BijuxError", 

104 "UserInputError", 

105 "PluginError", 

106 "InternalError", 

107 "ConfigError", 

108]