WJb Docs - Intermediate
Learn workflows, persistence, scheduling, and production-ready patterns.
π Start Here
π§© Mental Model
π Building Workflows
π₯ Failures & Control
π Observation & Debugging
π Practical Patterns
β Working Examples
β‘οΈ Whatβs Next
π₯ How Failures Work
Failures in WJb are explicit and simple.
An action signals failure by throwing an exception.
Throwing an Exception
public override async Task<IActionResult> ExecuteAsync(
EmailInput input, CancellationToken ct)
{
if (string.IsNullOrWhiteSpace(input.To))
throw new InvalidOperationException("Recipient address is required");
// send email...
return await CompleteAsync();
}
When an exception is thrown:
1. The job is marked as Failed
2. The exception details are stored
3. No further Next commands from this action are executed
What Gets Stored
The store records:
- Job status = Failed
- Error message
- Exception type and details (depending on the store)
Failure vs Complete / Next
| Outcome | How it is signaled | Result |
|-------------|---------------------------------|----------------------------|
| Success end | CompleteAsync() / Results.Complete | Job Completed |
| Continuation| NextAsync / Results.Next | New jobs enqueued |
| Failure | throw | Job Failed, error stored |
Example with Real Error
public override async Task<IActionResult> ExecuteAsync(
EmailInput input, CancellationToken ct)
{
try
{
await _emailService.SendAsync(input, ct);
return await CompleteAsync();
}
catch (SmtpException ex)
{
// Optional: log or transform the error
throw new InvalidOperationException("Failed to send email via SMTP", ex);
}
}
The original exception (or a wrapped one) becomes part of the jobβs failure information.
What Happens After Failure
By default the workflow stops for that branch.
Further behavior depends on:
- Retry settings in
JobOptions - Manual requeue
- Explicit failure commands (if you use
JobCommandCondition.Failure)
Best Practices
- Throw meaningful exceptions
- Prefer domain-specific exception types when useful
- Do not swallow exceptions unless you really intend to continue
- Always pass the
CancellationTokenso cancellation is not treated as a normal failure
Key Point
There is no special βfailβ return value required for most cases.
Just throw an exception β WJb records the failure and stops the current branch.