Check out the Error Handling guide to learn more about how Restate handles transient errors, terminal errors, retries, and timeouts.
Understanding Retryable vs Terminal Errors
Retryable errors are temporary problems that might succeed if retried:- Database connection timeout
- Network issues
- Temporary service unavailability
- Invalid user input (wrong format, missing required fields)
- Authorization failures (user doesn’t have permission)
- Business logic violations (insufficient balance, duplicate order)
TerminalErrors.
Raising TerminalError
Use TerminalError to signal permanent failures.
When you raise TerminalError in your handler code, it stops the invocation and marks it as permanently failed:
TerminalError inside a ctx.run block, it fails that specific step, allowing your handler to continue and handle the error:
ctx.run, all errors are retried unless you raise TerminalError explicitly or set up a run retry policy.
Common use cases for terminal error are:
- Input validation failures:
raise TerminalError("Invalid email format") - Business rule violations:
raise TerminalError("Insufficient balance") - Resource not found:
raise TerminalError("User ID not found")
When you throw a terminal error, you may need to undo previous actions to keep your system consistent. Check out our sagas guide to learn about compensations.
Handling Errors
Most of the time, you only need to catchTerminalError to handle permanent failures.
❌ Wrong - This leads to unexpected behavior:
Advanced: using finally for resource cleanup
Advanced: using finally for resource cleanup
Only use
finally blocks if you’re managing resources (files, connections, locks) that must be released even when retries happen.finally, understand what goes where:restate.is_internal_exception(e) to identify whether an exception is a Restate SDK internal exception that should be ignored.Key principle:except TerminalError: For compensations and business logic when the invocation permanently failsfinally: For releasing resources (files, connections) acquired during the current attempt