Coverage for src / lexigram / contracts / exceptions / components.py: 0%

58 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-08-15 18:57 +0800

1"""Consolidated component exceptions. 

2 

3These exceptions inherit from the canonical Lexigram hierarchy but provide 

4component-specific context where needed. 

5""" 

6 

7from __future__ import annotations 

8 

9from typing import Any 

10 

11from lexigram.contracts.exceptions import ( 

12 ConflictError, 

13 InfrastructureError, 

14 LexigramError, 

15 LockError, 

16 NotFoundError, 

17) 

18 

19 

20class ComponentError(LexigramError): 

21 """Base exception for all component-related errors.""" 

22 

23 _code = "LEX_ERR_INFRA_004" 

24 

25 def __init__( 

26 self, 

27 message: str, 

28 component_type: str | None = None, 

29 driver_type: str | None = None, 

30 details: dict[str, Any] | None = None, 

31 **kwargs: Any, 

32 ) -> None: 

33 details = details or {} 

34 if component_type: 

35 details["component_type"] = component_type 

36 if driver_type: 

37 details["driver_type"] = driver_type 

38 

39 super().__init__(message, details=details, **kwargs) 

40 self.component_type = component_type 

41 self.driver_type = driver_type 

42 

43 

44class ComponentConnectionError(InfrastructureError, ComponentError): 

45 """Raised when a connection to an external service fails.""" 

46 

47 _code = "LEX_ERR_INFRA_005" 

48 

49 def __init__(self, message: str, **kwargs: Any) -> None: 

50 super().__init__(message, **kwargs) 

51 

52 

53class KeyNotFoundError(NotFoundError, ComponentError): 

54 """Raised when a requested key does not exist.""" 

55 

56 _code = "LEX_ERR_INFRA_006" 

57 

58 def __init__(self, key: str, **kwargs: Any) -> None: 

59 super().__init__(f"Key not found: {key}", **kwargs) 

60 self.key = key 

61 

62 

63class KeyExistsError(ConflictError, ComponentError): 

64 """Raised when trying to create a key that already exists.""" 

65 

66 _code = "LEX_ERR_INFRA_007" 

67 

68 def __init__(self, key: str, **kwargs: Any) -> None: 

69 super().__init__(f"Key already exists: {key}", **kwargs) 

70 self.key = key 

71 

72 

73class PubSubError(InfrastructureError, ComponentError): 

74 """Base exception for pub/sub operations.""" 

75 

76 _code = "LEX_ERR_INFRA_008" 

77 

78 def __init__(self, message: str, topic: str | None = None, **kwargs: Any) -> None: 

79 details = kwargs.get("details", {}) 

80 if topic: 

81 details["topic"] = topic 

82 super().__init__(message, details=details, **kwargs) 

83 self.topic = topic 

84 

85 

86class SecretNotFoundError(NotFoundError, ComponentError): 

87 """Raised when a requested secret does not exist.""" 

88 

89 _code = "LEX_ERR_INFRA_009" 

90 

91 def __init__(self, secret_name: str, **kwargs: Any) -> None: 

92 super().__init__( 

93 f"Secret not found: {secret_name}", 

94 **kwargs, 

95 ) 

96 self.secret_name = secret_name 

97 

98 

99class LockAcquisitionError(LockError, ComponentError): 

100 """Raised when acquiring a lock fails.""" 

101 

102 _code = "LEX_ERR_LOCK_001" 

103 

104 def __init__(self, resource: str, message: str = "", **kwargs: Any) -> None: 

105 super().__init__( 

106 f"Failed to acquire lock on '{resource}': {message}", 

107 **kwargs, 

108 ) 

109 self.resource = resource 

110 

111 

112class LockNotHeldError(LockError, ComponentError): 

113 """Raised when trying to operate on a lock that is not held.""" 

114 

115 _code = "LEX_ERR_LOCK_002" 

116 

117 def __init__(self, resource: str, **kwargs: Any) -> None: 

118 super().__init__(f"Lock not held: {resource}", **kwargs) 

119 self.resource = resource 

120 

121 

122class DriverNotAvailableError(ComponentError): 

123 """Raised when a driver is not available (dependency not installed).""" 

124 

125 _code = "LEX_ERR_INFRA_010" 

126 

127 def __init__(self, driver_type: str, install_hint: str = "", **kwargs: Any) -> None: 

128 super().__init__( 

129 f"Driver not available: {driver_type}. Install with: {install_hint}", 

130 **kwargs, 

131 ) 

132 self.driver_type = driver_type 

133 self.install_hint = install_hint 

134 

135 

136__all__ = [ 

137 "ComponentConnectionError", 

138 "ComponentError", 

139 "DriverNotAvailableError", 

140 "KeyExistsError", 

141 "KeyNotFoundError", 

142 "LockAcquisitionError", 

143 "LockNotHeldError", 

144 "PubSubError", 

145 "SecretNotFoundError", 

146]