Interceptors wrap handler and ctx.run() execution. They are part of the
invocation — anything that happens inside them (including after next())
affects the invocation outcome.
Error behavior
Errors thrown at any point (before or after next()) affect the invocation:
TerminalError — the invocation fails immediately, no retry.
Any other error — Restate retries the invocation.
On suspension or pause, next() also rejects with an error. This does not
mean the invocation failed — the attempt is simply ending. Do any cleanup
you need and rethrow.
Output
Interceptors cannot alter the handler's success return value (the void
signature means there is no way to replace it), but they can transform
errors by catching and rethrowing a different error.
Rules
next() must be called exactly once.
When interceptors fire
handler fires on every attempt.
run fires when the ctx.run() closure executes. If the result is
already in the journal, the closure is skipped and so is the interceptor.
Example
interceptor: { handler: async (next) => { console.log(`before ${ctx.request.target}`); try { awaitnext(); 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). throwe; } }, run: async (name, next) => { console.log(` before run "${name}"`); try { awaitnext(); console.log(` after run "${name}"`); } catch (e) { console.log(` error run "${name}": ${e}`); throwe; } }, }
Interceptors wrap handler and ctx.run() execution. They are part of the invocation — anything that happens inside them (including after
next()) affects the invocation outcome.Error behavior
Errors thrown at any point (before or after
next()) affect the invocation:next()also rejects with an error. This does not mean the invocation failed — the attempt is simply ending. Do any cleanup you need and rethrow.Output
Interceptors cannot alter the handler's success return value (the
voidsignature means there is no way to replace it), but they can transform errors by catching and rethrowing a different error.Rules
next()must be called exactly once.When interceptors fire
handlerfires on every attempt.runfires when thectx.run()closure executes. If the result is already in the journal, the closure is skipped and so is the interceptor.Example