-
Notifications
You must be signed in to change notification settings - Fork 0
Workflow Try & Retry #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- add comprehensive tests for workflow registry and builder - test step execution paths and non-callable steps - cover ArgExpr coercion and expression chaining - test runtime router building with mixed step types - validate all error conditions and edge cases brings core modules from 88% to 99% coverage
- implement RetryPolicy with configurable backoff - add retry YAML emission in codegen - support retries for both Python steps and HttpSteps - include example payment workflow with retry logic - add comprehensive tests and snapshots allows steps to automatically retry on transient failures
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces try/catch blocks and retry policies to enhance workflow resilience. The implementation adds comprehensive error handling mechanisms that allow workflows to gracefully handle exceptions and recover from transient failures through configurable retry strategies.
- Adds
TryCatchStepandTryCatchBuilderfor structured exception handling with fallback logic - Implements
RetryPolicywith configurable backoff strategies for automatic retries on failures - Provides YAML code generation support for both try/catch blocks and retry configurations
Reviewed Changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/fastapi_cloudflow/core/error_handling.py | New module defining TryCatchStep and TryCatchBuilder classes for workflow exception handling |
| src/fastapi_cloudflow/codegen/workflows.py | Updates YAML generation to support try/catch blocks and retry policy emission |
| src/fastapi_cloudflow/init.py | Exports new try/catch functionality and helper functions |
| tests/unit/test_try_catch.py | Comprehensive unit tests for try/catch functionality |
| tests/unit/test_retry_policy.py | Unit tests for retry policy features |
| tests/codegen/test_try_catch_codegen.py | Tests for try/catch YAML code generation |
| tests/codegen/test_retry_codegen.py | Tests for retry policy YAML code generation |
| examples/app/flows/resilient_payment.py | Example workflow demonstrating retry and try/catch usage |
| examples/app/flows/data_pipeline.py | Complex data pipeline example with nested try/catch blocks |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| if node.raise_on_error: | ||
| # Add a step to re-raise the error after handling | ||
| except_steps.append({"reraise_error": {"raise": f"${{{node.error_var}}}"}}) | ||
| try_catch_def["except"]["steps"] = except_steps |
Copilot
AI
Sep 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reraise_error step is appended to the except_steps list after it has already been assigned to try_catch_def['except']['steps']. This creates a mutation after assignment issue. The reraise step should be appended before the assignment on line 163, or the assignment on line 167 should be removed since it's redundant.
| try_catch_def["except"]["steps"] = except_steps |
| # Manually make it async to avoid syntax issues | ||
| async_no_input = AsyncMock(side_effect=no_input_hint) | ||
| async_no_input.__name__ = "no_input_hint" |
Copilot
AI
Sep 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The comment mentions 'to avoid syntax issues' but this approach is overly complex and fragile. Consider using a proper async function definition or pytest.mark.asyncio instead of manually creating AsyncMock objects.
| output_model=PaymentResult, # Changed to match the actual output | ||
| try_steps=try_primary.nodes, | ||
| except_steps=[fallback_payment, log_failure], # Use actual step instances | ||
| error_var="payment_error", | ||
| raise_on_error=False, # Don't re-raise, we handled it |
Copilot
AI
Sep 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The inline comments on lines 115, 117, and 119 appear to be implementation notes rather than helpful code documentation. These should be removed or converted to proper documentation that explains the business logic.
| output_model=PaymentResult, # Changed to match the actual output | |
| try_steps=try_primary.nodes, | |
| except_steps=[fallback_payment, log_failure], # Use actual step instances | |
| error_var="payment_error", | |
| raise_on_error=False, # Don't re-raise, we handled it | |
| output_model=PaymentResult, | |
| try_steps=try_primary.nodes, | |
| except_steps=[fallback_payment, log_failure], | |
| error_var="payment_error", | |
| raise_on_error=False, |
| input_model=ProcessedData, | ||
| output_model=ProcessedData, | ||
| method="POST", | ||
| url="https://jsonplaceholder.typicode.com/posts", # Mock endpoint |
Copilot
AI
Sep 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Using a hardcoded mock endpoint URL in production code is not ideal. Consider using environment variables or configuration for external service URLs, even in examples.
| tc_step = ( | ||
| try_catch("custom-error-var").try_block(try_block).except_block(except_block, error_var="my_error").build() | ||
| ) |
Copilot
AI
Sep 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The line is split unnecessarily with parentheses. This could be written as a single line or use proper line continuation for better readability.
| tc_step = ( | |
| try_catch("custom-error-var").try_block(try_block).except_block(except_block, error_var="my_error").build() | |
| ) | |
| tc_step = try_catch("custom-error-var").try_block(try_block).except_block(except_block, error_var="my_error").build() |
b7fc83e to
2b9b5f3
Compare
feature #3 is now fully implemented with clean API
- add TryCatchStep and TryCatchBuilder for error recovery - support nested try/catch with custom error variables - emit proper Cloud Workflows try/except YAML syntax - include data pipeline example with multi-stage error handling - update README roadmap and mark features complete - expose new components in package __init__ enables robust error handling and fallback strategies in workflows
2b9b5f3 to
df49371
Compare
feature #3 is now fully implemented with clean API
Adds try/catch blocks and retry policies to enhance workflow resilience. This change introduces:
This enhancement improves the robustness and reliability of workflows by providing mechanisms to recover from transient failures and handle errors in a controlled manner.
Note
Introduce try/catch error handling and retry policies with full YAML/codegen support, new example workflows, and comprehensive tests/docs; bump version to 0.0.2.
TryCatchStep,TryCatchBuilder, andtry_catchAPI (core/error_handling.py); export viacore/__init__.pyand package__init__.py.retryconfig (predicate/backoff) andtimeoutper step; generatetry/exceptblocks forTryCatchStep.examples/app/flows/resilient_payment.pyanddata_pipeline.py; updateexamples/app/main.pyimports.Arg,RetryPolicy, step core/execution, workflow core, and try/catch.tests/codegen/...); update smoke runner script references.README.mdto mark Retries/Try-catch as supported and add roadmap; tweakCONTRIBUTING.mdand smoke instructions; add.cursor/rules/writing-tests.mdc.0.0.2.Written by Cursor Bugbot for commit df49371. This will update automatically on new commits. Configure here.