Errors Module¶
Exception hierarchy and error handling.
Exception Hierarchy¶
FlowEngineError (base)
├── ConfigurationError # Invalid configuration
├── FlowExecutionError # Runtime execution errors
│ ├── FlowTimeoutError # Timeout exceeded
│ └── DeadlineCheckError # Component didn't check deadline
├── ComponentError # Component processing error
└── ConditionEvaluationError # Invalid/unsafe condition
FlowEngineError¶
Base exception for all FlowEngine errors.
FlowEngineError
¶
Bases: Exception
Base exception for all FlowEngine errors.
ConfigurationError¶
Raised for configuration validation errors.
ConfigurationError
¶
ConfigurationError(message: str, config_path: Optional[str] = None, details: Optional[list[str]] = None)
Bases: FlowEngineError
Error in flow configuration.
Raised when there are issues with YAML parsing, schema validation, or invalid configuration values.
Attributes:
| Name | Type | Description |
|---|---|---|
config_path |
Path to the configuration file (if applicable) |
|
details |
List of specific validation errors |
FlowExecutionError¶
Raised for runtime execution errors.
FlowExecutionError
¶
Bases: FlowEngineError
Error during flow execution.
Raised when the flow execution fails for reasons other than component-specific errors.
Attributes:
| Name | Type | Description |
|---|---|---|
flow_id |
Unique identifier of the flow execution |
|
step |
Name of the step where error occurred |
FlowTimeoutError¶
Raised when execution exceeds the configured timeout.
FlowTimeoutError
¶
FlowTimeoutError(message: str, timeout: Optional[float], elapsed: float, flow_id: Optional[str] = None, step: Optional[str] = None)
Bases: FlowExecutionError
Error when flow execution exceeds timeout.
Raised when the total flow execution time exceeds the configured timeout_seconds value, or when a component's check_deadline() call detects the deadline has passed.
Attributes:
| Name | Type | Description |
|---|---|---|
timeout |
The configured timeout in seconds (None if from deadline check) |
|
elapsed |
How much time had elapsed when timeout occurred |
DeadlineCheckError¶
Raised when a component fails to call check_deadline().
DeadlineCheckError
¶
DeadlineCheckError(message: str, component: str, duration: float, threshold: float, flow_id: Optional[str] = None)
Bases: FlowExecutionError
Error when component fails to check deadline.
Raised when require_deadline_check is True and a long-running component does not call check_deadline() during execution. This enforces the cooperative timeout contract.
Attributes:
| Name | Type | Description |
|---|---|---|
component |
Name of the non-compliant component |
|
duration |
How long the component took to execute |
|
threshold |
The threshold above which deadline checks are required |
ComponentError¶
Raised when a component fails during processing.
ComponentError
¶
Bases: FlowEngineError
Error from a component.
Raised when a component fails during its lifecycle methods.
Attributes:
| Name | Type | Description |
|---|---|---|
component |
Name of the component that failed |
|
original_error |
The underlying exception (if any) |
ConditionEvaluationError¶
Raised for invalid or unsafe condition expressions.
ConditionEvaluationError
¶
Bases: FlowEngineError
Error evaluating a condition expression.
Raised when a condition expression is invalid, unsafe, or fails during evaluation.
Attributes:
| Name | Type | Description |
|---|---|---|
condition |
The condition expression string |
Usage Examples¶
Catching Specific Errors¶
from flowengine import (
FlowEngine,
ConfigLoader,
ConfigurationError,
FlowTimeoutError,
DeadlineCheckError,
ComponentError,
ConditionEvaluationError,
)
try:
config = ConfigLoader.load("flow.yaml")
engine = FlowEngine(config, components)
result = engine.execute()
except ConfigurationError as e:
print(f"Config error: {e.message}")
print(f"File: {e.config_path}")
for detail in e.details:
print(f" - {detail}")
except FlowTimeoutError as e:
print(f"Timeout at step '{e.step}'")
print(f"Elapsed: {e.elapsed:.2f}s")
print(f"Limit: {e.timeout}s")
except DeadlineCheckError as e:
print(f"Component '{e.component}' didn't check deadline")
print(f"Ran for {e.duration:.2f}s")
except ComponentError as e:
print(f"Component '{e.component}' failed")
print(f"Error: {e.message}")
if e.original_error:
print(f"Cause: {e.original_error}")
except ConditionEvaluationError as e:
print(f"Invalid condition: {e.condition}")
print(f"Error: {e.message}")
Raising Custom Errors¶
from flowengine import ComponentError, BaseComponent, FlowContext
class MyComponent(BaseComponent):
def process(self, context: FlowContext) -> FlowContext:
try:
result = self.risky_operation()
except ValueError as e:
raise ComponentError(
f"Invalid value in {self.name}",
component=self.name,
original_error=e,
)
context.set("result", result)
return context
Checking Error Attributes¶
try:
result = engine.execute()
except FlowTimeoutError as e:
# All attributes available
print(f"Message: {e.message}")
print(f"Flow ID: {e.flow_id}")
print(f"Step: {e.step}")
print(f"Timeout: {e.timeout}")
print(f"Elapsed: {e.elapsed}")
# Can re-raise with additional context
raise RuntimeError(f"Flow timed out at {e.step}") from e
Error Recovery Pattern¶
from flowengine import FlowEngineError
def execute_with_retry(engine, max_retries=3):
for attempt in range(max_retries):
try:
return engine.execute()
except FlowTimeoutError:
if attempt == max_retries - 1:
raise
print(f"Retry {attempt + 1}/{max_retries}")
except FlowEngineError:
# Don't retry other errors
raise