Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Task

A Task is an individual processing unit within a workflow that executes a function.

Overview

Tasks are the building blocks of workflows. Each task:

  • Executes a single function (built-in or custom)
  • Can have a condition for conditional execution
  • Can modify message data
  • Records changes in the audit trail

Task Structure

{
    "id": "transform_data",
    "name": "Transform Data",
    "condition": { "!!": {"var": "data.input"} },
    "continue_on_error": false,
    "function": {
        "name": "map",
        "input": {
            "mappings": [
                {
                    "path": "data.output",
                    "logic": {"var": "data.input"}
                }
            ]
        }
    }
}

Fields

FieldTypeRequiredDescription
idstringYesUnique task identifier within workflow
namestringNoHuman-readable name
conditionJSONLogicNoWhen to execute task
continue_on_errorbooleanNoContinue workflow on failure
functionobjectYesFunction to execute

Function Configuration

The function object specifies what the task does:

{
    "function": {
        "name": "function_name",
        "input": { ... }
    }
}

Built-in Functions

FunctionPurpose
mapData transformation and field mapping
validationData validation with custom error messages

Custom Functions

Register custom functions when creating the engine:

#![allow(unused)]
fn main() {
let engine = Engine::new(workflows, Some(custom_functions));
}

Then reference them by name in tasks:

{
    "function": {
        "name": "my_custom_function",
        "input": { ... }
    }
}

Conditional Execution

Tasks can have conditions that determine if they should run:

{
    "id": "premium_greeting",
    "condition": { "==": [{"var": "data.tier"}, "premium"] },
    "function": {
        "name": "map",
        "input": {
            "mappings": [
                {"path": "data.greeting", "logic": "Welcome, VIP member!"}
            ]
        }
    }
}

Common Patterns

// Only if field exists
{"!!": {"var": "data.email"}}

// Only if field equals value
{"==": [{"var": "data.status"}, "active"]}

// Only if numeric condition
{">=": [{"var": "data.amount"}, 100]}

// Combine conditions
{"and": [
    {"!!": {"var": "data.email"}},
    {"==": [{"var": "data.verified"}, true]}
]}

Error Handling

Task-Level Error Handling

{
    "id": "optional_task",
    "continue_on_error": true,
    "function": { ... }
}

When continue_on_error is true:

  • Task errors are recorded in message.errors
  • Workflow continues to the next task

Workflow-Level Error Handling

The workflow’s continue_on_error setting applies to all tasks unless overridden.

Sequential Execution

Tasks execute in order within a workflow. Later tasks can use results from earlier tasks:

{
    "tasks": [
        {
            "id": "step1",
            "function": {
                "name": "map",
                "input": {
                    "mappings": [
                        {"path": "temp_data.intermediate", "logic": {"var": "data.raw"}}
                    ]
                }
            }
        },
        {
            "id": "step2",
            "function": {
                "name": "map",
                "input": {
                    "mappings": [
                        {"path": "data.final", "logic": {"var": "temp_data.intermediate"}}
                    ]
                }
            }
        }
    ]
}

Try It

Try changing tier to “standard” to see different discount applied.

Best Practices

  1. Unique IDs - Use descriptive, unique IDs for debugging
  2. Single Responsibility - Each task should do one thing well
  3. Use temp_data - Store intermediate results in temp_data
  4. Conditions - Add conditions to skip unnecessary processing
  5. Error Handling - Use continue_on_error for optional tasks