Try/Catch
Wraps a subgraph with failure-handling semantics:
- Try — the subgraph to execute. Failures inside this branch are swallowed rather than failing the whole workflow.
- Catch — runs only if any node inside the Try branch failed.
- Finally — always runs after Try/Catch finishes (regardless of success or failure). Useful for cleanup, logging, or emitting metrics.
When to use
- Calling flaky external APIs where failures are expected and you want a graceful fallback.
- Critical side-effects that need a clean-up regardless of outcome (e.g. always close a session, always log a result).
- Wrapping optional enrichment that shouldn't break the main flow if it fails.
Configuration
Try/Catch has no configuration fields — it's purely a routing node. The behaviour is determined by which handles you wire.
Handles
- Try — entry into the protected subgraph.
- Catch — fires only if any node inside the Try branch threw an error.
- Finally — fires after both Try and Catch have settled.
What it outputs
Try/Catch writes a summary of the execution:
{
tryStatus: "success" | "error",
errorMessage: null | "...",
errorNodeId: null | "...",
caughtAt: "2026-04-18T09:00:00.000Z"
}Inside the Catch branch, reference {{try_catch.data.errorMessage}} to log or route based on what failed.
Example: best-effort enrichment
[Trigger] → [Try/Catch]
↘ try → [Gateway Call: lookup customer]
→ [Transform: enrich payload]
↘ catch → [Transform: use trigger data unchanged]
↘ finally → [Gateway Call: record metric]If the customer lookup fails, the flow continues with just the trigger data. The metric is recorded either way.
Gotchas
- Try branch executes eagerly: nodes inside run sequentially. A failure stops further Try nodes and jumps to Catch — you don't need explicit failure-wiring between nodes.
- Catch doesn't automatically retry — if you want retries, wrap the risky node in a Retry block instead of (or in addition to) Try/Catch.
- Finally branch runs serially after the others, not in parallel — don't expect it to race Try/Catch to completion.