Error Handling
This example demonstrates how to create a workflow with robust error handling patterns. We’ll build a simple API lookup workflow that attempts to retrieve information from an external service and provides manual recovery when the API fails.
Note: This example uses
create_mock
tools for demonstration purposes to keep the example simple and focused on core workflow concepts. In real-world use cases, you would replace these mock tools with actual tools that perform the specific processing operations your automation requires (such as API calls, data transformations, file operations, or LLM interactions).
Example: API Lookup with Error Handling
The workflow demonstrates error handling through a simple API lookup that fails and provides manual recovery:
In this example:
- API call fails and transitions to error state
- Error handler displays the error message and creates retry interface
- User can manually retry by returning to the start state
- This creates a loop where the original API call is re-attempted
workflows:
- name: failing_workflow
type: stateMachine
transitions:
- name: call_api # Step 1: Attempt to call external API
from: start
to:
- api_success
- api_failed
onError: api_failed # Go here if an error occurs
call:
- tool: create_mock
arguments:
input: 'weather for San Francisco'
error: 'API service unavailable: 503 Service Temporarily Unavailable' # Throw an error for demonstration
as: API_RESULT
- tool: create_chat_message # This tool call will not execute, since an error occurred before
arguments:
role: 'assistant'
content: 'Weather data retrieved: {{ API_RESULT }}'
# Success path
- name: display_result # Normal completion when API succeeds
from: api_success
to: end
call:
- tool: create_chat_message
arguments:
role: 'assistant'
content: '✅ API lookup completed successfully!'
# Error handling path
- name: handle_api_error # Handle API failure
from: api_failed
to: waiting_for_retry
call:
- tool: create_error_message
arguments:
message: ${ data.call_api.error } # Access error from previous transition
- tool: create_document
arguments:
document: retry_form
content:
message: "API call failed. Click 'Retry' to attempt the request again."
timestamp: "{{ currentDate }}"
# Manual recovery transition
- name: retry_api_call # User can manually retry the API call
from: waiting_for_retry
to: start # Return to start to retry the original API call
when: manual # Wait for user interaction
The retry form provides user interface for manual recovery:
documents:
- name: retry_form
schema:
type: object
properties:
message:
type: string
timestamp:
type: string
ui:
properties:
message:
title: "Status"
readonly: true
timestamp:
title: "Error Time"
readonly: true
buttons:
- transition: retry_api_call
label: "Retry"
enabledWhen:
- waiting_for_retry
Key Concepts:
- Form Fields: Read-only fields display error status and timestamp
- Action Button: “Retry” button triggers the
retry_api_call
transition - State Control: Button only enabled when workflow is in
waiting_for_retry
state
Understanding Error Handling
The workflow demonstrates the core error handling pattern with manual recovery:
API Call with Error Handling
- name: call_api
from: start
to:
- api_success # Success path
- api_failed # Alternative path (unused in this example)
onError: api_failed # Error path (when exception occurs)
call:
- tool: create_mock
arguments:
input: 'weather for San Francisco'
error: 'API service unavailable: 503 Service Temporarily Unavailable' # Triggers error
as: API_RESULT
- tool: create_chat_message # This will not execute due to the error above
arguments:
role: 'assistant'
content: 'Weather data retrieved: {{ API_RESULT }}'
Key Concepts:
- Error Simulation: The
error
property triggers theonError
path - Tool Chain Interruption: When an error occurs, subsequent tool calls in the same transition are skipped
- State Transition: Error moves workflow to
api_failed
state for handling
Error Recovery with Manual Intervention
- name: handle_api_error
from: api_failed
to: waiting_for_retry
call:
- tool: create_error_message
arguments:
message: ${ data.call_api.error } # Access the error from the failed transition
- tool: create_document
arguments:
document: retry_form
content:
message: "API call failed. Click 'Retry' to attempt the request again."
timestamp: "{{ currentDate }}"
Key Concepts:
- Error Access: Use
${ data.call_api.error }
to access the error message from the failed transition - Error Display:
create_error_message
shows the error in a dedicated UI component - User Interface: Document creates an interactive form for user recovery actions
Manual Retry Transition
- name: retry_api_call
from: waiting_for_retry
to: start # Return to start to retry the original operation
when: manual # Waits for user to click retry button
Key Concepts:
- Manual Transition:
when: manual
pauses workflow for user input - Minimal Logic: Retry transition simply returns to start without additional tool calls
- Loop Pattern: Creates a retry loop where users can attempt the operation multiple times
Error Data Access
The workflow demonstrates how to access error information from failed transitions:
# In the error handling transition
call:
- tool: create_error_message
arguments:
message: ${ data.call_api.error } # Access error from the 'call_api' transition
Data Access Pattern:
- Error Messages: Use
${ data.TRANSITION_NAME.error }
to access error details - Transition Data: Each transition’s data is available through the
data
object - Error Display: Built-in tools like
create_error_message
format errors for user display
Running This Example
This example is already available in Loopstack Studio and configured to demonstrate error handling:
- Navigate to the Studio interface
- Switch to the examples workspace
- Select “Example 5: Error Handling” from the available automations
- Observe the API failure error message displayed by
create_error_message
- See the retry form with status information and timestamp
- Click “Retry” to return to start and attempt the API call again
- Notice how the workflow creates a retry loop, allowing multiple attempts
Configuration Location: You can also view the complete configuration file at src/config/examples/basic/workflow-error-handling-example.yaml
Complete Example:
include:
- core/tools/create-mock.yaml
- core/tools/create-chat-message.yaml
- core/tools/create-error-message.yaml
- core/tools/create-document.yaml
pipelines:
- name: error_handling_example
title: "Example 5: Error Handling"
type: root
workspace: examples
sequence:
- workflow: failing_workflow
workflows:
- name: failing_workflow
type: stateMachine
transitions:
- name: call_api # Step 1: Attempt to call external API
from: start
to:
- api_success
- api_failed
onError: api_failed # Go here if an error occurs
call:
- tool: create_mock
arguments:
input: 'weather for San Francisco'
error: 'API service unavailable: 503 Service Temporarily Unavailable' # Throw an error for demonstration
as: API_RESULT
- tool: create_chat_message # This tool call will not execute, since an error occurred before
arguments:
role: 'assistant'
content: 'Weather data retrieved: {{ API_RESULT }}'
# Success path
- name: display_result # Normal completion when API succeeds
from: api_success
to: end
call:
- tool: create_chat_message
arguments:
role: 'assistant'
content: '✅ API lookup completed successfully!'
# Error handling path
- name: handle_api_error # Handle API failure
from: api_failed
to: waiting_for_retry
call:
- tool: create_error_message
arguments:
message: ${ data.call_api.error } # Access error from previous transition: data.<transition>.error
- tool: create_document
arguments:
document: retry_form
content:
message: "API call failed. Click 'Retry' to attempt the request again."
timestamp: "{{ currentDate }}"
# Manual recovery transition
- name: retry_api_call # User can manually retry the API call
from: waiting_for_retry
to: start # Return to start to retry the original API call
when: manual # Wait for user interaction
documents:
- name: retry_form
schema:
type: object
properties:
message:
type: string
timestamp:
type: string
ui:
properties:
message:
title: "Status"
readonly: true
timestamp:
title: "Error Time"
readonly: true
buttons:
- transition: retry_api_call
label: "Retry"
enabledWhen:
- waiting_for_retry