Portal Community
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

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

PortDescription
successFires 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

FieldTypeDescription
successboolAlways 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

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

ExpressionDescription
{{ $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).