Coverage for src/dataknobs_fsm/core/exceptions.py: 85%

40 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-08 14:11 -0700

1"""FSM Core Exceptions Module. 

2 

3This module defines core exception types used throughout the FSM system. 

4Now built on the common exception framework from dataknobs_common. 

5""" 

6 

7from typing import Any, Dict 

8 

9from dataknobs_common import ( 

10 ConcurrencyError as BaseConcurrencyError, 

11 ConfigurationError, 

12 DataknobsError, 

13 OperationError, 

14 ResourceError as BaseResourceError, 

15 TimeoutError as BaseTimeoutError, 

16 ValidationError as BaseValidationError, 

17) 

18 

19# Create FSMError as alias to DataknobsError for backward compatibility 

20FSMError = DataknobsError 

21 

22 

23class InvalidConfigurationError(ConfigurationError): 

24 """Raised when FSM configuration is invalid.""" 

25 pass 

26 

27 

28class StateExecutionError(OperationError): 

29 """Raised when state execution fails.""" 

30 

31 def __init__(self, state_name: str, message: str, details: Dict[str, Any] | None = None): 

32 super().__init__( 

33 f"State '{state_name}' execution failed: {message}", 

34 context=details 

35 ) 

36 self.state_name = state_name 

37 

38 

39class TransitionError(OperationError): 

40 """Raised when state transition fails.""" 

41 

42 def __init__(self, from_state: str, to_state: str, message: str, details: Dict[str, Any] | None = None): 

43 super().__init__( 

44 f"Transition from '{from_state}' to '{to_state}' failed: {message}", 

45 context=details 

46 ) 

47 self.from_state = from_state 

48 self.to_state = to_state 

49 

50 

51class ResourceError(BaseResourceError): 

52 """FSM-specific resource error with resource_id tracking. 

53 

54 Extends the common ResourceError with FSM-specific resource tracking. 

55 """ 

56 

57 def __init__(self, resource_id: str, message: str, details: Dict[str, Any] | None = None): 

58 super().__init__( 

59 f"Resource '{resource_id}' error: {message}", 

60 context=details 

61 ) 

62 self.resource_id = resource_id 

63 

64 

65# Use common ValidationError directly (no FSM-specific behavior needed) 

66ValidationError = BaseValidationError 

67 

68 

69class FunctionError(OperationError): 

70 """Raised when a function execution fails. 

71 

72 This represents deterministic failures in user-defined functions 

73 (transforms, validators, conditions) that should not be retried. 

74 These are code errors, not transient failures. 

75 """ 

76 

77 def __init__( 

78 self, 

79 message: str, 

80 function_name: str | None = None, 

81 from_state: str | None = None, 

82 to_state: str | None = None, 

83 details: Dict[str, Any] | None = None, 

84 ): 

85 if function_name: 

86 message = f"Function '{function_name}' failed: {message}" 

87 super().__init__(message, context=details) 

88 self.function_name = function_name 

89 self.from_state = from_state 

90 self.to_state = to_state 

91 

92 

93# Use common TimeoutError directly (no FSM-specific behavior needed) 

94TimeoutError = BaseTimeoutError 

95 

96 

97# Use common ConcurrencyError directly (no FSM-specific behavior needed) 

98ConcurrencyError = BaseConcurrencyError 

99 

100 

101class CircuitBreakerError(BaseConcurrencyError): 

102 """Raised when circuit breaker is open.""" 

103 

104 def __init__(self, wait_time: float | None = None, details: Dict[str, Any] | None = None): 

105 if wait_time: 

106 message = f"Circuit breaker is open (wait {wait_time:.1f}s)" 

107 else: 

108 message = "Circuit breaker is open" 

109 super().__init__(message, context=details) 

110 self.wait_time = wait_time 

111 

112 

113class ETLError(OperationError): 

114 """Raised when ETL operations fail.""" 

115 pass 

116 

117 

118class BulkheadTimeoutError(BaseTimeoutError): 

119 """Raised when bulkhead queue times out.""" 

120 pass