Portal Community
Required pairing: CatchBlock must always follow a TryBlock. It fires only when an unhandled exception is thrown inside the TryBlock scope. On the success path (no exception), the CatchBlock is skipped and execution proceeds to FinallyBlock (if present) or continues normally.

When to Use

Configuration

FieldRequiredDescription
Behavior Optional Controls what happens after the catch scope completes. Valid values: continue (default) — execution continues to FinallyBlock and then the rest of the workflow; stop — execution halts after the catch scope (FinallyBlock still runs); transform — the exception is transformed into a structured output and passed downstream.
ErrorVariablePrefix Optional Custom prefix for the three exception variables. Default prefix is empty, producing __exception_type__, __exception_message__, __exception_stacktrace__. Set to e.g. paymentErr for nested try/catch blocks to avoid variable name collisions: paymentErr_type__, paymentErr_message__, etc.

Behavior Values

ValueBehaviour After Catch Scope Completes
continueThe workflow continues normally after the catch scope. Execution proceeds to FinallyBlock (if present) and then to whatever follows the try/catch/finally block. Use when the error was handled and the workflow can safely resume.
stopWorkflow execution stops after the catch scope. FinallyBlock still runs (for cleanup), but no further workflow nodes execute after FinallyBlock. Use when the error is unrecoverable and the workflow must not continue.
transformThe caught exception is converted to a structured data output. The catch scope can modify the error data, and execution continues — with the transformed error data available to downstream nodes. Use when you want to convert exceptions into structured error response objects.

Output Ports

PortFires When
successAn exception was caught and the catch scope nodes should execute. Error variables are populated. Connect logging, alerting, and recovery nodes here.
errorThe CatchBlock itself encountered an error during its own initialisation (rare — typically a configuration issue). Always wire this port to prevent silent failure of error handling.

Exception Variables Written to Memory

When CatchBlock fires, the following variables are written into ExecutionMemory. Access them with $var.<name>:

Variable (default prefix)TypeDescription
__exception_type__stringThe .NET exception class name — e.g. HttpRequestException, TimeoutException, KeyNotFoundException. Use with Switch for type-specific handling.
__exception_message__stringHuman-readable description of the exception. Include in alert notifications and error log records.
__exception_stacktrace__stringFull .NET stack trace. Valuable for debugging. Include in error log inserts; do not expose to end users.

With ErrorVariablePrefix: "payErr", the variables become:

Variable (custom prefix)Description
payErr_type__Exception type with custom prefix.
payErr_message__Exception message with custom prefix.
payErr_stacktrace__Stack trace with custom prefix.

OutputData Fields

The CatchBlock's own output data (accessible via $output.<catchNodeKey>):

FieldTypeDescription
__exception_type__stringException type (same as the memory variable).
__exception_message__stringException message.
__exception_stacktrace__stringStack trace.

Sample Output

Error Port — Exception Caught

{
  "error": {
    "errorCode": "HTTP_REQUEST_FAILED",
    "message": "Connection refused: upstream API at https://api.external.com/orders returned 503",
    "statusCode": 503,
    "nodeName": "fetchOrders",
    "nodeType": "HttpRequest",
    "timestamp": "2025-03-15T09:45:22.000Z"
  },
  "context": {
    "workflowId": "wf_order_sync",
    "executionId": "exec_20250315_001",
    "attemptNumber": 1
  }
}

Expression Reference

ExpressionReturns
{{ $var.__exception_type__ }}Exception class name, e.g. HttpRequestException
{{ $var.__exception_message__ }}Error message string
{{ $var.__exception_stacktrace__ }}Full stack trace (multi-line string)
{{ $output.myCatch.__exception_type__ }}Same, accessed via node output reference

Validation Errors

ErrorCause
VAL_INVALID_BEHAVIORBehavior is set to a value other than continue, stop, or transform.
VAL_CATCH_WITHOUT_TRYCatchBlock is placed in the workflow without a preceding TryBlock in scope.

Node Policies and GuardRails

Pattern Examples

Pattern 1 — Log Error and Continue

If an optional enrichment call fails, log it to the database and set a default value. The main workflow continues normally with the default value.

TryBlock  [key: "enrichTry"]
  └─► success ──► HttpRequest  [key: "enrichApi"]
                    GET /enrich/{{ $json.customerId }}
                    └─► VariableAssignment (creditScore = response.score)
CatchBlock  [key: "enrichCatch"]
  Behavior: continue
  └─► success ──► MongoDB  (insert into enrichment_errors:
                             { type: {{ $var.__exception_type__ }},
                               msg:  {{ $var.__exception_message__ }},
                               customerId: {{ $json.customerId }} })
                    └─► VariableAssignment (creditScore = -1)  (default)
FinallyBlock  [key: "enrichFinally"]
  └─► success ──► [use $var.creditScore — either real or default]

Pattern 2 — Type-Based Exception Routing

Route different exception types to different handlers using Switch on the exception type variable.

CatchBlock  [key: "apiCatch"]
  Behavior: continue
  └─► success ──► Switch  [key: "routeByError"]
                    Expression: {{ $var.__exception_type__ }}
                    Cases: {
                      "HttpRequestException": "handleNetworkError",
                      "UnauthorizedException": "handleAuthError",
                      "TimeoutException":      "handleTimeout"
                    }
                    DefaultPort: "handleUnknownError"
                    ├─► handleNetworkError ──► Delay (2s) ──► [retry]
                    ├─► handleAuthError    ──► EmailSmtp (alert: auth expired)
                    ├─► handleTimeout      ──► SlackNode (alert: API slow)
                    └─► handleUnknownError ──► MongoDB (log full stack trace)

Pattern 3 — Stop on Critical Failure with Notification

For unrecoverable failures (e.g., a core data write), stop the workflow after alerting the team. FinallyBlock still runs to update the status record.

CatchBlock  [key: "criticalCatch"]
  Behavior: stop
  └─► success ──► SlackNode  (#critical-alerts)
                    Message: "CRITICAL: {{ $var.__exception_type__ }} in OrderWrite
                              {{ $var.__exception_message__ }}
                              OrderId: {{ $json.orderId }}"
                    └─► MongoDB  (insert into failed_orders:
                                  { orderId, exceptionType, exceptionMsg, ts })
FinallyBlock  [key: "criticalFinally"]
  └─► success ──► MongoDB  (update orders SET status='failed'
                             WHERE id={{ $json.orderId }})