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
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-08 14:11 -0700
1"""FSM Core Exceptions Module.
3This module defines core exception types used throughout the FSM system.
4Now built on the common exception framework from dataknobs_common.
5"""
7from typing import Any, Dict
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)
19# Create FSMError as alias to DataknobsError for backward compatibility
20FSMError = DataknobsError
23class InvalidConfigurationError(ConfigurationError):
24 """Raised when FSM configuration is invalid."""
25 pass
28class StateExecutionError(OperationError):
29 """Raised when state execution fails."""
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
39class TransitionError(OperationError):
40 """Raised when state transition fails."""
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
51class ResourceError(BaseResourceError):
52 """FSM-specific resource error with resource_id tracking.
54 Extends the common ResourceError with FSM-specific resource tracking.
55 """
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
65# Use common ValidationError directly (no FSM-specific behavior needed)
66ValidationError = BaseValidationError
69class FunctionError(OperationError):
70 """Raised when a function execution fails.
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 """
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
93# Use common TimeoutError directly (no FSM-specific behavior needed)
94TimeoutError = BaseTimeoutError
97# Use common ConcurrencyError directly (no FSM-specific behavior needed)
98ConcurrencyError = BaseConcurrencyError
101class CircuitBreakerError(BaseConcurrencyError):
102 """Raised when circuit breaker is open."""
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
113class ETLError(OperationError):
114 """Raised when ETL operations fail."""
115 pass
118class BulkheadTimeoutError(BaseTimeoutError):
119 """Raised when bulkhead queue times out."""
120 pass