feat: workflow try helpers & visualizer support#4413
Merged
NathanFlurry merged 7 commits intomainfrom Mar 31, 2026
Merged
Conversation
|
🚅 Deployed to the rivet-pr-4413 environment in rivet-frontend
|
Member
Author
PR Review: feat: workflow try helpers and visualizer support. This PR adds ctx.tryStep() and ctx.try() to the workflow engine for recovering from terminal failures without disrupting scheduler control flow, plus visualizer and docs support. The design is solid overall with some items worth addressing. CORRECTNESS: Bug fix in race winner detection: The old winnerValue !== null check would incorrectly skip returning when a branch legitimately yields null. The new hasWinner boolean flag is the right fix. Scheduler yield propagation in join/race branches: The new mergeSchedulerYield / selectControlFlowError plumbing correctly handles retrying steps inside join/race branches, which previously could corrupt branch state by marking a retrying branch as failed. markErrorReported + attachTryStepFailure chaining: Both helpers mutate the error in-place and return it, so chaining markErrorReported(attachTryStepFailure(err, ...)) correctly preserves both Symbol properties on the same object. ISSUES: 1. parseStoredWorkflowError vs extractErrorInfo inconsistency: getTryStepFailureFromExhaustedError uses parseStoredWorkflowError(error.lastError) while every other failure builder uses extractErrorInfo(liveError). The two paths produce subtly different results as extractErrorInfo also captures stack and enumerable metadata while parseStoredWorkflowError only gets name/message. A comment explaining why the string-parse path is needed here would prevent future confusion. 2. TryBlockFailure.source maps to TryBlockCatchKind inconsistently: In shouldCatchTryBlockFailure, a RollbackError thrown directly inside a ctx.try block gets source block, but users must put rollback in their catch list to intercept it. The mismatch between the source name and the catch kind will surprise callers. Consider renaming source block to source rollback, or adding an explicit block catch kind. 3. Missing guard when run is not passed to the string-overload of tryStep: The non-null assertion run! silently passes undefined at runtime if the caller forgets the second argument. The ctx.try wrapper already throws explicitly. Consider adding the same guard to tryStep string overload. 4. Step rollback inside ctx.try requires rollback in catch, but other step failures only require step: DEFAULT_TRY_BLOCK_CATCH does not catch rollback-kind step failures. This is intentional since rollbacks signal programmer errors, but it is a sharp edge not mentioned in the docs or QUICKSTART.md. A single sentence noting this distinction would prevent confusion. NITS: 5. Missing comment on new HistoryDivergedError guards: The new if (!branchStatus) checks in join/race are correct defensive guards. A short comment noting that this triggers when the workflow definition changes between runs would help. 6. No test for nested ctx.try inside ctx.try: Nested try blocks are a worthwhile edge case to add. TEST COVERAGE: try.test.ts covers the main happy and sad paths well. The additions to join.test.ts and race.test.ts for retry-within-branch correctness are particularly valuable since those fixed real bugs. The integration test in actor-workflow.ts closes the loop at the RivetKit layer. SUMMARY: The core design is clean and the scheduler yield refactor in join/race is a genuine improvement. Items 2 and 4 are the most likely to cause real user confusion and are worth addressing before merge. |
Member
Author
000ae2a to
c58143b
Compare
f92fb2f to
08d9f1e
Compare
11 tasks
Member
Author
This stack of pull requests is managed by Graphite. Learn more about stacking. |
11 tasks
8fb8fed to
769e543
Compare
08d9f1e to
ef43f37
Compare
769e543 to
ba155ee
Compare
ef43f37 to
022a7a3
Compare
022a7a3 to
fe2bd86
Compare
Member
Author
Merge activity
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.






Description
Adds
ctx.tryStep()andctx.try()to the workflow engine and RivetKit wrapper so workflows can recover from terminal step, join, and race failures without swallowing scheduler control flow. It also updates the workflow visualizer to render named try scopes and handled failures, plus adds docs, stories, and integration coverage for the new behavior.Type of change
How Has This Been Tested?
pnpm exec vitest run tests/try.test.ts tests/join.test.ts tests/race.test.tsinrivetkit-typescript/packages/workflow-enginepnpm exec vitest run tests/driver-memory.test.ts -t "tryStep and try recover terminal workflow failures"inrivetkit-typescript/packages/rivetkitpnpm test workflow-to-xyflowinfrontendpnpm exec biome check src/components/actors/workflow/workflow-to-xyflow.ts src/components/actors/workflow/workflow-to-xyflow.test.ts src/components/actors/workflow/xyflow-nodes.tsx src/components/actors/workflow/workflow-visualizer.tsx src/components/actors/workflow/workflow-example-data.ts src/components/actors/workflow/xyflow-nodes.stories.tsxinfrontendChecklist: