TryBlock try-block
Open a guarded execution scope. Any unhandled exception thrown by nodes inside the try block is intercepted and routed to the paired CatchBlock instead of failing the workflow. Calls Memory.EnterTryBlock() and creates a new variable scope.
TryBlock, CatchBlock, and FinallyBlock work together. Always use all three in sequence: TryBlock marks the guarded region, CatchBlock handles exceptions, and FinallyBlock runs cleanup regardless of outcome. A TryBlock without a CatchBlock will fail workflow validation.
The Try / Catch / Finally Pattern
TryBlock
Marks the start of the guarded region. All nodes connected downstream from TryBlock's success port are inside the protected scope. If any node throws an exception, execution immediately jumps to the CatchBlock. On the success path (no exception), execution flows normally and reaches FinallyBlock after the try body.
CatchBlock
Fires only when an exception was thrown inside the TryBlock scope. Exception details are injected into memory: __exception_type__, __exception_message__, __exception_stacktrace__. Use this scope for error logging, notifications, fallback logic, and recovery. After CatchBlock, execution continues to FinallyBlock.
FinallyBlock (recommended)
Fires always — after both the successful try path and after the catch path. Use for guaranteed cleanup: releasing locks, closing connections, writing audit logs. Calls Memory.ExitTryBlock() and Memory.ExitVariableScope().
When to Use
- External API calls: Wrap HttpRequest nodes calling payment gateways, ERPs, or third-party services. API failures are common — network errors, rate limits, service outages — and must be handled gracefully rather than crashing the workflow.
- Database write operations: Wrap database insert/update nodes when the write may fail due to constraint violations, connection issues, or timeouts. The CatchBlock can log the failure and the FinallyBlock releases any acquired locks.
- File operations: Wrap S3 uploads, file downloads, or document generation steps. On failure, the CatchBlock can retry or use a fallback path without losing the rest of the workflow context.
- Optional enrichment steps: Wrap enrichment API calls that are non-critical. If enrichment fails, the CatchBlock sets default values and execution continues on the main path without interruption.
- Multi-step atomic operations: Wrap a sequence of related writes that must all succeed together. If any step fails, the CatchBlock can roll back or compensate previous steps.
Configuration
No configuration required. TryBlock has no settings. Place it in the workflow before the nodes you want to protect and connect its
success port to the first protected node. Then connect the CatchBlock downstream from TryBlock's scope.
Output Ports
| Port | Description |
|---|---|
success | Fires immediately when TryBlock executes — it simply opens the guarded scope and passes execution to the first node inside the try body. No delay or condition. |
OutputData Fields
| Field | Type | Description |
|---|---|---|
success | bool | Always true — the TryBlock node itself always succeeds. The try body nodes may or may not succeed; that is what the CatchBlock handles. |
Node Policies and GuardRails
- Must always be paired with CatchBlock: A TryBlock without a downstream CatchBlock fails workflow validation. The engine must know where to route exceptions from the try scope.
- FinallyBlock is strongly recommended: Any workflow that acquires a resource (a lock, a session, a file handle) inside the try scope must use a FinallyBlock to guarantee release. FinallyBlock is the only reliable way to ensure cleanup runs on both the success and error paths.
- Use for external and risky operations: Wrap API calls, database writes, file operations, and any node whose failure should be handled rather than propagated. For pure internal logic (IfCondition, Switch, VariableAssignment), TryBlock is generally unnecessary.
- Nested TryBlocks are supported: You can place a TryBlock inside another TryBlock's body for fine-grained exception isolation. Inner exceptions are caught by the inner CatchBlock; outer exceptions by the outer one.
- Variable scope isolation: Variables set inside the try scope are accessible throughout the try/catch/finally trio. Variables set after the FinallyBlock cannot see variables set only inside the try scope.
Pattern Examples
Pattern 1 — Protected External API Call
Wrap a payment API call in try/catch/finally. On failure, log the error and notify the team. FinallyBlock always releases the transaction lock.
VariableAssignment (acquire transaction lock)
└─► TryBlock [key: "paymentTry"]
└─► success ──► HttpRequest [key: "chargeCard"]
POST /payments/charge
└─► VariableAssignment (store confirmation)
CatchBlock [key: "paymentCatch"]
Behavior: continue
└─► success ──► MongoDB (insert to payment_errors collection)
└─► EmailSmtp (alert payments team)
FinallyBlock [key: "paymentFinally"]
└─► success ──► VariableAssignment (release transaction lock)
└─► [continue workflow regardless]
Pattern 2 — Optional Enrichment with Graceful Degradation
Attempt to enrich a customer record with credit bureau data. If the call fails, set default values and continue. The main workflow is never blocked by enrichment failures.
TryBlock [key: "enrichTry"]
└─► success ──► HttpRequest [key: "creditBureau"]
GET /credit/{{ $json.customerId }}
└─► VariableAssignment
creditScore = $output.creditBureau.score
CatchBlock [key: "enrichCatch"]
Behavior: continue
└─► success ──► VariableAssignment
creditScore = -1 (default: unknown)
└─► MongoDB (log enrichment failure for retry queue)
FinallyBlock [key: "enrichFinally"]
└─► success ──► [continue with $var.creditScore — set by either try or catch]
Pattern 3 — Database Write with Rollback on Failure
Write to two tables that must both succeed. If either write fails, the CatchBlock runs compensating deletes. FinallyBlock logs the final outcome.
TryBlock [key: "writeTry"]
└─► success ──► MongoDB [key: "writeOrder"]
insert order document
└─► MongoDB [key: "writeAudit"]
insert audit log entry
CatchBlock [key: "writeCatch"]
Behavior: stop
ErrorVariablePrefix: write_err
└─► success ──► MongoDB (delete order if it was created)
└─► SlackNode (alert: DB write failure)
FinallyBlock [key: "writeFinally"]
└─► success ──► MongoDB (insert outcome audit entry: success or failure)
Sample Output
Success Port — Try Succeeded
{
"invoiceId": "INV-2025-00123",
"vendorName": "Acme Supplies Ltd",
"amount": 4500.00,
"currency": "USD",
"approvedBy": "finance-team",
"processedAt": "2025-03-15T11:20:00Z",
"_tryBlock": {
"succeeded": true,
"nodesExecuted": 3
}
}
Error Port — Caught Exception (routes to CatchBlock)
{
"_tryBlock": {
"succeeded": false,
"errorCode": "HTTP_TIMEOUT",
"message": "Request to payment gateway timed out after 30s",
"failedNode": "chargeCard",
"failedAt": "2025-03-15T11:20:28.000Z"
}
}
Expression Reference
| Expression | Description |
|---|---|
{{ $output.tryNode._tryBlock.succeeded }} | true on the success port; false when routed to CatchBlock. |
{{ $output.tryNode._tryBlock.errorCode }} | Error code when the Try sequence failed. |
{{ $output.tryNode._tryBlock.failedNode }} | Name of the node inside the Try sequence that threw the error. |
{{ $output.tryNode.invoiceId }} | Any field from the last successful node's output (on success port). |