OptionalabortOptionalasBy default, Restate treats errors as terminal (non-retryable) only when they are instances of TerminalError.
Use this hook to map domain-specific errors to TerminalError (or return undefined to keep them retryable).
When mapped to TerminalError, the error will not be retried.
Note: This applies to errors thrown inside ctx.run closures as well as errors thrown by Restate handlers.
Example:
class MyValidationError extends Error {}
const greeter = restate.service({
name: "greeter",
handlers: {
greet: async (ctx: restate.Context, name: string) => {
if (name.length === 0) {
throw new MyValidationError("Length too short");
}
return `Hello ${name}`;
}
},
options: {
asTerminalError: (err) => {
if (err instanceof MyValidationError) {
// My validation error is terminal
return new restate.TerminalError(err.message, { errorCode: 400 });
}
// Any other error is retryable
}
}
});
Optional ExperimentalexplicitWhen set to true, the SDK will stop automatically propagating cancellations when awaiting RestatePromises.
Instead, the user code must explicitly listen to cancellations using the ctx.cancellation() API in ContextInternal.
OptionalhooksHooks providers for this service. Service-level hooks wrap outermost —
they run before handler-level hooks. Both levels are merged: service
hooks first, then handler hooks. Within each level, hooks execute in
array order: for [A, B]: A before → B before → handler → B after → A after.
The handler interceptor fires on every attempt. The run interceptor
fires only when the ctx.run() closure actually executes — replayed
runs (already in the journal) are skipped.
Errors thrown at any point (before or after next()) affect the invocation:
TerminalError fails immediately, any other error triggers a retry.
On suspension or pause, next() also rejects — do any cleanup and rethrow.
const myService = restate.service({
name: "MyService",
handlers: { greet: async (ctx, name) => `Hello, ${name}!` },
options: {
hooks: [
(ctx) => ({
interceptor: {
handler: async (next) => {
console.log(`before ${ctx.request.target}`);
try {
await next();
console.log(`after ${ctx.request.target}`);
} catch (e) {
console.log(`error ${ctx.request.target}: ${e}`);
// Always rethrow — swallowing the error changes the
// invocation outcome. You can also throw a different
// error (e.g. TerminalError to fail immediately).
throw e;
}
},
run: async (name, next) => {
console.log(` before run "${name}"`);
try {
await next();
console.log(` after run "${name}"`);
} catch (e) {
console.log(` error run "${name}": ${e}`);
throw e;
}
},
},
}),
],
},
});
OptionalidempotencyThe retention duration of idempotent requests to this service.
Note: Available only when registering this endpoint with restate-server v1.4 or newer; otherwise service discovery will fail.
OptionalinactivityGuards against stalled invocations. Once this timeout expires, Restate requests a graceful suspension of the invocation (preserving intermediate progress).
If the invocation does not react to the suspension request, abortTimeout is used to abort it.
Overrides the default inactivity timeout configured in the Restate server for all invocations to this service.
Note: Available only when registering this endpoint with restate-server v1.4 or newer; otherwise service discovery will fail.
OptionalingressWhen set to true, this service (and all its handlers) cannot be invoked via the Restate server
HTTP or Kafka ingress; it can only be called from other services.
Note: Available only when registering this endpoint with restate-server v1.4 or newer; otherwise service discovery will fail.
OptionaljournalJournal retention applied to all requests to all handlers of this service.
When a request includes an idempotency key, idempotencyRetention caps the journal retention time.
Note: Available only when registering this endpoint with restate-server v1.4 or newer; otherwise service discovery will fail.
OptionalretryRetry policy to apply to all requests to this service. For each unspecified field, the default value configured in the restate-server configuration file will be applied instead.
OptionalserdeDefault serde to use for requests, responses, state, side effects, awakeables, promises. Used when no other serde is specified.
If not provided, defaults to serde.json.
Guards against invocations that fail to terminate after inactivity. The abort timeout starts after
inactivityTimeoutexpires and a graceful termination was requested. When this timer expires, the invocation is aborted.This timer may interrupt user code. If more time is needed for graceful termination, increase this value.
Overrides the default abort timeout configured in the Restate server for invocations to this service.
Note: Available only when registering this endpoint with restate-server v1.4 or newer; otherwise service discovery will fail.