Skip to main content

Conditional Flow Control

This document demonstrates how to use conditional flow features in the Kuetix workflow system, including on success when, if, else, continue on fail, and skip to.

For the expression language itself, let bindings, and the foreach / while / retry constructs, see Expressions, let, Loops & Retry.

Overview​

The workflow system supports several conditional and control flow features:

  1. on success when: Conditional transitions taken only when a step succeeds AND a condition is truthy. A state may carry several — they are evaluated top to bottom, first match wins — with a plain on success as the fallback.
  2. if: Pre-condition that must be met before a state executes
  3. else: Alternate path when the if condition is false
  4. continue on fail: Flag to continue execution even if a step fails
  5. skip to: Flag to skip to a specific state
  6. let: Bind an intermediate value before the action — see the linked page

Conditions are evaluated at runtime against the workflow context. Earlier engine builds parsed on success when but did not gate on it; current builds do.

WSL Syntax Examples​

Example 1: Basic if Condition​

workflow conditional_example {
start: ConditionalCheck

state ConditionalCheck {
if $constants.enabled == true
action services/common/process.Execute(config: "main") as Result
on success -> ProcessResult
on error -> HandleError
}

state ProcessResult {
action services/common/response.ResponseValue(message: "Processed successfully")
end ok
}

state HandleError {
action services/common/response.ResponseValue(message: "Processing failed")
end error
}
}

Example 2: Continue on Fail​

workflow resilient_workflow {
start: RiskyOperation

state RiskyOperation {
continue on fail
action services/common/risky.Execute() as Result
on success -> Success
on error -> ContinueAnyway
}

state Success {
action services/common/response.ResponseValue(message: "Operation succeeded")
end ok
}

state ContinueAnyway {
action services/common/response.ResponseValue(message: "Operation failed but continuing")
end ok
}
}

Example 3: Skip To​

workflow skip_example {
start: OptionalStep

state OptionalStep {
skip to
action services/common/optional.Process() as OptResult
on success -> FinalStep
}

state FinalStep {
action services/common/response.ResponseValue(message: "Done")
end ok
}
}

Example 4: On Success When (ordered guards)​

Guards are checked in source order; the first truthy one wins. Add a plain on success last as the fallback.

workflow quota_check {
start: CheckQuota

state CheckQuota {
action services/quota/check.UserQuota(userId: $request.userId) as QuotaResult
on success when $QuotaResult.remaining > 0 -> AllowOperation
on success when $QuotaResult.remaining == 0 -> QuotaExceeded
on success -> AllowOperation
}

state AllowOperation {
action services/operation/execute.Process(userId: $request.userId)
end ok
}

state QuotaExceeded {
action services/response/error.QuotaExceeded(message: "No quota remaining")
end error
}
}

Example 5: Combined Attributes​

const {
enabled: true,
threshold: 10
}

workflow combined_example {
start: ComplexState

state ComplexState {
if $constants.enabled == true
continue on fail
action services/common/complex.Process(data: $request.data) as ProcessResult
on success when $ProcessResult.score > $constants.threshold -> HighScorePath
on success when $ProcessResult.score <= $constants.threshold -> LowScorePath
on error -> ErrorPath
}

state HighScorePath {
action services/common/response.ResponseValue(message: "High score achieved")
end ok
}

state LowScorePath {
action services/common/response.ResponseValue(message: "Low score")
end ok
}

state ErrorPath {
action services/common/response.ResponseValue(message: "Error but continuing due to continue on fail")
end ok
}
}

Advanced Usage​

Combining if with on success when​

state ConditionalStep {
if $feature.enabled == true
action services/process/execute.Process() as Result
on success when $Result.score > 80 -> HighScorePath
on success -> LowScorePath
on else -> FeatureDisabled
}

Execution flow:

  1. First, if condition is evaluated
  2. If false, flow goes to else path
  3. If true, the step executes
  4. After successful execution, on success when is evaluated
  5. Based on the result, flow goes to appropriate path

Key Features​

  1. Backward Compatible: Existing flows without new attributes work unchanged
  2. Expression Support: Uses the same expression parser as existing conditions
  3. Context Access: Can access workflow context, parent context, and result values
  4. Flexible: Attributes can be combined for complex flow control
  5. WSL Native: First-class syntax support in WSL for all attributes

Common Use Cases​

  1. if: Pre-execution validation, feature flags, environment checks
  2. on success when: Data validation, quota checks, business rules
  3. continue on fail: Resilient processing, optional operations
  4. skip to: Optional steps, conditional execution paths
  5. else: Fallback paths, error handling

JSON Equivalent (Legacy)​

For reference, the WSL features map to the following JSON structure:

Example 1: on_success_when (Simple Condition)​

{
"name": "validate_and_process",
"transitions": [
{
"name": "validate_data",
"to": "validate",
"on_success_when": "<<result.isValid>> == true",
"true": "process_data",
"false": "handle_invalid_data"
}
]
}

Example 2: if Condition​

{
"name": "conditional_execution",
"transitions": [
{
"name": "check_enabled",
"to": "process",
"if": "<<feature.enabled>> == true",
"true": "execute_feature",
"else": "skip_feature"
}
]
}

Example 3: continue_on_fail​

{
"name": "resilient_processing",
"transitions": [
{
"name": "may_fail_step",
"to": "risky_operation",
"continue_on_fail": true,
"true": "success_path",
"false": "failure_path"
}
]
}

Example 4: skipTo​

{
"name": "skip_processing",
"transitions": [
{
"name": "skip_step",
"to": "optional_step",
"skipTo": true,
"true": "next_step"
}
]
}