Error Handling
Error handling steps allow flows to respond to exceptional conditions, stop execution when needed, and communicate errors to callers.
Continue On Error
Every flow step exposes a Continue On Error setting. When a step fails (throws), its behavior depends on this flag:
| Setting | Behavior on failure |
|---|---|
| Continue On Error = false (default) | The flow halts and the error propagates to the caller |
| Continue On Error = true | The failure is suppressed and the flow continues with the next step |
Use Continue On Error for non-critical steps whose failure should not abort the whole flow (for example a best-effort notification or an optional enrichment call). For steps where a failure genuinely invalidates the process, leave it off so the error surfaces and any transaction is rolled back.
Raise Error
Throws an error that stops flow execution with a message.
| Parameter | Description |
|---|---|
| Error Code | A code identifying the error type |
| Error Message | Description of the error |
When Raise Error executes:
- Flow execution stops immediately
- The error is propagated to the caller
- Any transaction in progress is rolled back
- The error code and message are available to calling flows
Example - Validation Error:
CONDITION: Is Valid Input?
Condition: Input.Amount > 0 AND Input.CustomerId != null
FALSE BRANCH:
RAISE ERROR
Error Code: "INVALID_INPUT"
Error Message: "Amount must be positive and Customer must be specified"
Example - Business Rule Error:
# Check credit limit
RUN LOGIC BLOCK
Logic Block: CheckCreditLimit
→ RemainingCredit
CONDITION: Sufficient Credit?
Condition: Order.TotalAmount <= RemainingCredit
FALSE BRANCH:
RAISE ERROR
Error Code: "CREDIT_EXCEEDED"
Error Message: "Order amount (" + FORMAT(Order.TotalAmount, "C") +
") exceeds available credit (" + FORMAT(RemainingCredit, "C") + ")"
Example - Integration Error:
CALL REST API
Service Connection: PaymentGateway
Operation: ProcessPayment
→ PaymentResult, HttpStatus
CONDITION: Payment Failed?
Condition: HttpStatus >= 400 OR PaymentResult.Status == "declined"
TRUE BRANCH:
RAISE ERROR
Error Code: "PAYMENT_FAILED"
Error Message: "Payment declined: " + PaymentResult.DeclineReason
Halt
Stops the entire flow execution immediately without raising an error.
| Parameter | Description |
|---|---|
| (none) | Halt takes no parameters |
Unlike Raise Error, Halt stops execution gracefully:
- No error is propagated
- Outputs set before Halt are returned
- The transaction is committed (not rolled back)
Example - Early Exit:
# Check if processing is needed
EXECUTE QUERY
Entity: Order
Conditions: OrderId == InputOrderId AND Status == "Processed"
→ ExistingOrder
CONDITION: Already Processed?
Condition: ExistingOrder != null
TRUE BRANCH:
SET OUTPUT
AlreadyProcessed: true
Message: "Order was already processed"
HALT
Example - Conditional Processing:
# Check feature flag
RUN LOGIC BLOCK
Logic Block: GetConfigurationValue
Inputs: { Key: "EnableNewFeature" }
→ FeatureEnabled
CONDITION: Feature Disabled?
Condition: FeatureEnabled == false
TRUE BRANCH:
SET OUTPUT
Skipped: true
Reason: "Feature not enabled"
HALT
# Continue with feature logic...
Error Handling Patterns
Validation Before Processing
Validate all inputs before starting any data modifications:
# 1. Validate all inputs first
CONDITION: Missing Required Fields?
Condition: Input.CustomerId == null OR Input.Amount == null
TRUE BRANCH:
RAISE ERROR
Error Code: "MISSING_REQUIRED"
Error Message: "CustomerId and Amount are required"
CONDITION: Invalid Amount?
Condition: Input.Amount <= 0
TRUE BRANCH:
RAISE ERROR
Error Code: "INVALID_AMOUNT"
Error Message: "Amount must be greater than zero"
# 2. Validate business rules
RUN LOGIC BLOCK
Logic Block: ValidateOrderRules
→ IsValid, ValidationErrors
CONDITION: Business Rules Failed?
Condition: IsValid == false
TRUE BRANCH:
RAISE ERROR
Error Code: "BUSINESS_RULE_VIOLATION"
Error Message: ValidationErrors
# 3. Now safe to proceed with data operations
SAVE ENTITY...
Try-Catch Pattern with Sub-Flows
Handle errors from sub-flows gracefully:
# Main flow calls sub-flow that might fail
RUN LOGIC FLOW
Logic Flow: RiskyOperation
Inputs: { Data: InputData }
→ Success, ErrorMessage, Result
CONDITION: Sub-Flow Failed?
Condition: Success == false
TRUE BRANCH:
# Log the error
SAVE ENTITY
Entity: ErrorLog
Data: {
Operation: "RiskyOperation",
ErrorMessage: ErrorMessage,
InputData: TOSTRING(InputData),
OccurredOn: NOW()
}
# Decide how to proceed
CONDITION: Is Retryable?
Condition: CONTAINS(ErrorMessage, "timeout")
TRUE BRANCH:
# Could implement retry logic
...
FALSE BRANCH:
RAISE ERROR
Error Code: "OPERATION_FAILED"
Error Message: "Operation failed: " + ErrorMessage
FALSE BRANCH:
# Continue with Result
...
Graceful Degradation
Continue processing even when some operations fail:
NEW VARIABLE: Errors (List of String)
NEW VARIABLE: SuccessCount = 0
ITERATOR: Process Each Item
Collection: ItemsToProcess
Item Variable: Item
Steps:
# Try to process
RUN LOGIC FLOW
Logic Flow: ProcessSingleItem
Inputs: { Item: Item }
→ ItemSuccess, ItemError
CONDITION: Item Failed?
Condition: ItemSuccess == false
TRUE BRANCH:
# Record error but continue
UPDATE VARIABLE
Variable: Errors
Set Variable: APPEND(Errors, "Item " + Item.Id + ": " + ItemError)
FALSE BRANCH:
UPDATE VARIABLE
Variable: SuccessCount
Set Variable: SuccessCount + 1
# After processing all items
CONDITION: Any Errors?
Condition: COUNT(Errors) > 0
TRUE BRANCH:
# Log errors but don't fail completely
SAVE ENTITY
Entity: ProcessingLog
Data: {
TotalItems: COUNT(ItemsToProcess),
SuccessCount: SuccessCount,
ErrorCount: COUNT(Errors),
ErrorDetails: JOIN(Errors, "; ")
}
SET OUTPUT
Success: SuccessCount > 0
ProcessedCount: SuccessCount
ErrorCount: COUNT(Errors)
Best Practices
Fail Fast: Validate inputs and check preconditions early, before starting data modifications.
Use Meaningful Error Codes: Error codes should be consistent and identifiable. Use a naming convention like "CATEGORY_SPECIFIC_ERROR".
Provide Helpful Messages: Error messages should explain what went wrong and, if possible, how to fix it.
Log Before Raising: For important errors, create a log record before raising the error so you have an audit trail.
Don't Swallow Errors: If something fails unexpectedly, don't hide it. Either handle it properly or let it propagate.
Consider the Caller: Design your error responses thinking about what the calling flow or system needs to know.
Use Halt for Expected Exits: Use Halt for expected early exits (like "nothing to process"). Use Raise Error for actual problems.
Test Error Paths: Make sure to test what happens when things fail, not just the happy path.