Errors
The FlexiQException hierarchy — catch by specific type or by the base.
The FlexiQException hierarchy — catch by specific type or by the base.
Every error the SDK throws extends FlexiQException (an unchecked
RuntimeException), so a single catch can scope all of them; the subclasses
under org.byteveda.flexiq.errors let you branch on what went wrong.
try {
flexiq.enqueue(sendPromo, audience);
} catch (PredicateRejectedException rejected) {
respond(409, "blocked by policy");
} catch (FlexiQException other) {
report(other);
}| Class | Extends | Thrown when |
|---|---|---|
FlexiQException | RuntimeException | Base; also carries native (JNI) errors directly. |
ConfigurationException | FlexiQException | The SDK is misconfigured — e.g. a missing connection URL. |
SerializationException | FlexiQException | A payload, options blob, or native response can't be (de)serialized. |
CryptoException | SerializationException | A signing/encrypting serializer or codec failed — bad signature, short payload, cipher error. |
PredicateRejectedException | FlexiQException | A registered predicate rejected an enqueue; no job was created. |
EnqueueSkippedException | FlexiQException | A gate returned Skip — enqueue throws; use tryEnqueue to get an empty Optional instead. |
InterceptionException | FlexiQException | An interceptor rejected an enqueue. |
LockException | FlexiQException | A distributed-lock operation failed or was interrupted. |
ResourceException | FlexiQException | A worker resource couldn't be built, resolved, or disposed — including Resources.use outside a task. |
ProxyException | FlexiQException | A proxy reference couldn't be created or reconstructed — no handler, signature mismatch, allowlist violation. |
DuplicateTaskException | FlexiQException | Two handlers claim one task name — two providers on the classpath, or discover() landing on a name already registered on the builder. See Task discovery. |
TaskDiscoveryException | FlexiQException | A handler provider couldn't be loaded from the classpath, or threw while building its handlers. Never skipped. |
WebhookException | FlexiQException | A webhook couldn't be stored, loaded, signed, or encoded. |
WorkflowException | FlexiQException | Workflow definition, submission, await-timeout, or query error. |
RetryableException | FlexiQException | You throw it from a handler: this failure is transient, retry it. |
NonRetryableException | FlexiQException | You throw it from a handler: this failure is permanent, dead-letter it. |
Handler exceptions are different: an exception thrown inside a
TaskFunction isn't rethrown to you — it fails that attempt, and the core
retries with the task's backoff until the retry budget is spent, then
dead-letters the job. Inspect those via jobErrors(id) and listDead.
The last two rows above travel the other way — a handler throws them to
classify its own failure, overriding the task's retryOn predicate:
queue.worker().handle(CHARGE, (Order order) -> {
Response response = gateway.charge(order);
if (response.status() == 402) {
throw new NonRetryableException("card declined"); // dead-letters now
}
if (response.status() >= 500) {
throw new RetryableException("gateway " + response.status()); // spends the budget
}
return response.body();
});Both are honoured through the cause chain, so a signal wrapped by framework
code still counts; when a chain carries both, the outermost wins. Any other
exception is classified by the task's retryOn
predicate, and retries
when there is none.