When automations interact with external APIs, things go wrong -- servers return errors, rate limits get hit, connections drop. The Automation Engine provides several mechanisms to handle failures gracefully: updating item fields when errors occur, retrying trigger calls with backoff, tolerating pagination errors, and logging everything for diagnosis.
Object Failure Updates
The object_failure_update configuration lets you automatically update fields on a product or order when an export API call fails. This is powerful for tracking which items failed, what error occurred, and routing them for manual review.
Basic Configuration
"object_failure_update": {
"errorCode": 400,
"errorMessage": "Invalid SKU",
"updates": {
"export_status": "failed",
"export_error": "Invalid SKU returned by vendor API"
}
}
When the API returns HTTP 400 and the response body contains "Invalid SKU", the engine sets export_status to "failed" and export_error to the specified message on the affected product or order.
Matching Options
You can match errors in several ways:
| Key | Type | Description |
|---|---|---|
| errorCode | int or array | Match on HTTP status code(s). Example: 400 or [400, 422, 500] |
| errorMessage | string or array | Match when the response body contains this string (or any string in the array). |
| errorRegex | string | Match when the response body matches this regular expression. Takes precedence over errorMessage if both are set. |
| errorKey | string | For 200 responses that contain errors in the payload. Specifies the key in the JSON response to check for error content. |
| errorPosition | array | [start, end] indices to slice the response before matching. Useful when the response is large and you only want to check a portion. |
| updates | object | Key/value pairs to set on the product or order when the error matches. Required. |
Matching HTTP Error Responses (Status >= 300)
The most straightforward case: the API returns an error HTTP status code.
"object_failure_update": {
"errorCode": [400, 422],
"updates": {
"vendor_sync_status": "error",
"vendor_sync_date": "{{NOW}}"
}
}
If no errorCode, errorMessage, or errorRegex is specified, the update applies to any HTTP error (status >= 300).
Matching Errors in 200 Responses
Some APIs return HTTP 200 but include error information in the response body. Use errorKey to extract and check a specific field:
"object_failure_update": {
"errorKey": "errors[0].message",
"errorMessage": "out of stock",
"updates": {
"channel_status": "sync_failed",
"channel_error": "Vendor reports out of stock"
}
}
The engine reads the value at errors[0].message in the JSON response. If that value contains "out of stock", the updates are applied. If errorMessage is omitted, any non-empty value at errorKey triggers the match.
Matching with Regex
For complex error patterns, use errorRegex:
"object_failure_update": {
"errorRegex": "/SKU .+ not found in catalog/i",
"updates": {
"export_status": "sku_not_found"
}
}
Multiple Error Handlers
To handle different errors differently, use an array of configurations:
"object_failure_update": [
{
"errorCode": 429,
"updates": {
"export_status": "rate_limited"
}
},
{
"errorCode": 404,
"updates": {
"export_status": "not_found_on_vendor"
}
},
{
"errorMessage": "duplicate",
"updates": {
"export_status": "duplicate_rejected"
}
}
]
The engine checks each configuration in order. When a match is found, those updates are applied and the error is considered "handled." If no configuration matches, the error is recorded in the automation log as an unhandled failure.
Trigger Retries
When using triggers (multi-step API workflows), each trigger object supports retry configuration for handling transient failures:
"triggers": [
{
"key": "job_id",
"address": "https://api.vendor.com/exports",
"method": "POST",
"max_retries": 5,
"retry_time": 300,
"retry_time_fixed": false
}
]
| Key | Description | Default |
|---|---|---|
| max_retries | Number of times to retry the trigger call. | 3 |
| retry_time | Base wait time in seconds. For the first retry the full value is used; subsequent retries multiply by the attempt number squared (see table below). | 3600 (1 hour) |
| retry_time_fixed | If true, wait the same retry_time for each retry. If false, use exponential backoff. | false |
Exponential Backoff
With the default retry_time_fixed: false, the wait time increases quadratically (multiplied by the attempt number squared):
| Attempt | Multiplier (attempts²) | Wait Time (retry_time = 300) |
|---|---|---|
| 1st retry | 1 | 300 seconds (5 min) |
| 2nd retry | 4 | 1,200 seconds (20 min) |
| 3rd retry | 9 | 2,700 seconds (45 min) |
This is useful for APIs where a job might need several minutes to complete. The first retry checks quickly, and subsequent retries back off to give the job more time.
With retry_time_fixed: true, every retry waits exactly retry_time seconds. This is better for APIs with predictable processing times.
Pagination Error Handling
When paginating through API responses, you may encounter errors partway through. By default, any error during pagination fails the entire automation. To handle this more gracefully:
"pagination": {
"next_token": "next",
"ignore_errors": true
}
When ignore_errors is true, the engine tolerates HTTP 500 errors during pagination and still processes all the pages it successfully retrieved. (HTTP 404 errors are always tolerated during pagination regardless of this setting.) This is useful when:
- An API returns 404 when you go past the last page (handled automatically, no configuration needed)
- Intermittent 500 errors should not discard pages already downloaded
- You prefer partial data over no data
Connection Failure Behavior
For HTTP connections, the engine automatically retries on transient connection failures (timeouts, DNS resolution failures, connection resets) up to 3 times before giving up. This is handled internally and does not require configuration.
For FTP and SFTP connections, similar automatic retry logic applies to connection establishment and file transfer operations.
Automation Logs
All errors, retries, and failure updates are recorded in the automation logs, accessible from the SureDone UI:
- Navigate to Automations in the left sidebar.
- Find the automation and click to view its details.
- Open the Logs tab.
Each log entry shows:
- Timestamp of the event
- Whether it was a success or failure
- HTTP status code and response body (for API errors)
- Which object_failure_update rules matched (if any)
- Trigger retry attempts and wait times
- Total items processed, updated, skipped, and failed
Example: Order Export with Error Handling
{
"name": "Order Export to Vendor",
"vendor": "Fulfillment Co",
"active": true,
"schedule": "*/10 * * * *",
"type": "orders",
"action": "export",
"connection": {
"type": "http",
"address": "https://api.fulfillment.co/orders",
"method": "POST",
"headers": {
"Authorization": "Bearer {{api_token}}",
"Content-Type": "application/json"
}
},
"file_configs": [
{
"search": "status:=awaiting_shipment",
"template": "... order JSON template ...",
"payload_multi": false,
"object_failure_update": [
{
"errorCode": 400,
"errorMessage": "Invalid address",
"updates": {
"status": "address_error",
"fulfillment_note": "Vendor rejected: invalid shipping address"
}
},
{
"errorCode": [500, 502, 503],
"updates": {
"fulfillment_note": "Vendor API error - will retry"
}
},
{
"errorKey": "errors[0].code",
"errorMessage": "OUT_OF_STOCK",
"updates": {
"status": "backorder",
"fulfillment_note": "Vendor reports item out of stock"
}
}
],
"order_update_export": {
"status": "submitted_to_vendor"
}
}
]
}
In this automation:
- Orders with status "awaiting_shipment" are exported one-by-one (payload_multi: false).
- On success, the order status is updated to "submitted_to_vendor."
- If the vendor returns HTTP 400 with "Invalid address", the order is flagged with "address_error."
- If the vendor has a server error (500/502/503), a note is added but the status is not changed, allowing the next run to retry.
- If the vendor returns 200 but includes an "OUT_OF_STOCK" error code in the response body, the order is moved to "backorder."