Exception handling
Exception handling controls whether Sixpack waits, retries, or fails a dataset.
Use this page for the common behaviour that applies to all SDKs. For exact class names and imports, see the SDK-specific pages:
Which exception to use
Use exceptions to describe what Sixpack should do next:
| Situation | What to do | Result |
|---|---|---|
| The dataset is waiting for an external process that may finish later | Halt the current iteration and ask Sixpack to retry after a delay | The same dataset starts another iteration after the delay |
| The current input can never produce a valid dataset | Throw a non-retryable exception | The current dataset is marked as failed and is not retried as-is |
| An Orchestrator cannot obtain a requested child dataset | Let the request failure propagate or wrap it with a clearer business message | The current Orchestrator attempt fails |
Generator failures
A Generator should throw a non-retryable exception when retrying the same dataset with the same input would not help.
Typical cases:
- a requested email, username, or external id already exists
- the input combination is invalid for the target system
- the target system rejected the request for a business reason that will not change on retry
When this happens, Sixpack marks the Generator dataset as failed. It does not retry that same dataset task with the same input.
If the problem may resolve with time, do not throw a non-retryable exception. Halt the current iteration and retry after a delay instead.
Orchestrator failures
An Orchestrator requests data from other items through its request methods. If the requested child dataset fails, the request method throws an obtain-failed exception in the Orchestrator.
The Orchestrator can:
- let the obtain-failed exception propagate
- catch it and throw a non-retryable exception with a clearer business message
Both options fail the current Orchestrator attempt. Sixpack can then retry the Orchestrator task from the beginning according to the normal retry policy.
This distinction matters:
- The failed child dataset is not retried as-is when it failed with a non-retryable exception.
- The Orchestrator retry starts the flow again. Earlier steps may produce different generated values, so the downstream constraint may no longer be violated.
Constraint violation example
Imagine this flow:
- Generator A generates a random email.
- Generator B creates a customer record in the CRM with the email as input.
- Orchestrator C first requests A, then requests B with A's email.
If B fails because the email is already used, B should throw a non-retryable exception. The request from C to B then throws an obtain-failed exception in C, and the current Orchestrator attempt fails.
When Sixpack retries C, the flow starts from the beginning. A can generate a new email, and B may succeed with that new value.
A better strategy, when feasible, is for Generator A to check the CRM before returning the email. That avoids the exception and the Orchestrator retry.
Practical rules
- Make Generators idempotent. A retry after process restart should not corrupt target-system state.
- Use delayed iteration for waiting and polling.
- Use non-retryable exceptions for invalid input and permanent business failures.
- Keep non-retryable exception messages useful for users and support teams.
- In Orchestrators, catch obtain-failed exceptions only when you can add a clearer business message.