Executor Patterns
How to run executors safely: error propagation, registration lifecycle, and the practices that keep executor contracts small and testable. The PostboyExecutor<T> contract and the exec verb are covered in Executors.
Error handling
Exceptions propagate synchronously
Postboy does not catch handler exceptions. A throw inside the handler surfaces at the exec call site, exactly like a direct function call:
Unregistered executors throw
Calling exec on an ID that was never registered fails with a TypeError — the bus calls an undefined handler. Wrap calls in try/catch where registration is not guaranteed, or guarantee registration at startup.
Expected failures: return a result
When failure is part of the domain, return an error-shaped result instead of throwing:
Rule of thumb: throw when the caller cannot proceed; return a result when the caller must branch on the outcome.
Middleware cancellation
Middleware can interrupt an exec; the call then throws a CancelError (identify it with error.name === 'PostboyCancelError'). Catch it where cancellation is expected — see Middleware Cancellation.
Lifecycle
Register executors in _up() of a registrator; down() disconnects everything the registrator recorded:
Without a registrator, remove a handler manually by its message ID:
See Lifecycle Management for scoping strategies.
Best practices
One executor, one operation. Split classes that accumulate unrelated responsibilities; the contract stays obvious and the handler easy to test.
Keep the payload minimal. Pass only what the handler needs — no flag arguments that belong elsewhere.
Make the result type meaningful.
{ success: false; reason }beats a barebooleanwhen callers must react to failure.Do not use executors as events. A notification nobody answers is a
PostboyGenericMessage, not an executor — see Events.Test handlers in isolation. A
PostboyExecutionHandleris a plain class; callhandle(...)directly in unit tests without the bus.Keep domain and infrastructure executors apart.
ConnectMessage,ConnectExecutor, andConnectHandlerwire the bus; domain executors carry business operations — see Infrastructure Messages.