Class: Runner<MiddlewareFn>
Runner executes an array of middleware functions in sequence.
The middleware pipeline advances only when the current function calls next, implementing the chain of responsibility pattern. You control how to execute the underlying middleware functions by providing an executor function.
Example
const context = { stack: [] };
type MiddlewareFn = (ctx: typeof context, next: NextFn) => void | Promise<void>;
const middleware = new Middleware<MiddlewareFn>();
middleware.add((ctx, next) => {
ctx.stack.push("fn1");
await next();
});
await middleware
.runner()
.finalHandler(() => {
context.stack.push("final handler");
})
.run((fn, next) => fn(context, next));Type Parameters
| Type Parameter | Description |
|---|---|
MiddlewareFn extends any | The type of the middleware function/handler |
Constructors
Constructor
new Runner<MiddlewareFn>(middleware: MiddlewareFn[]): Runner<MiddlewareFn>;Parameters
| Parameter | Type |
|---|---|
middleware | MiddlewareFn[] |
Returns
Runner<MiddlewareFn>
Methods
errorHandler()
errorHandler(errorHandler: ErrorHandler): this;Sets a custom error handler to catch exceptions in the middleware pipeline.
By default, exceptions raised in the middleware pipeline bubble up to the run method and can be captured using a try/catch block. When an exception is raised, the middleware downstream logic will not run.
Defining an error handler changes this behavior:
- The
runmethod will not throw exceptions - Errors are caught and passed to the error handler
- Middleware upstream logic (after
next) can still execute
Parameters
| Parameter | Type | Description |
|---|---|---|
errorHandler | ErrorHandler | The function to handle errors |
Returns
this
The Runner instance for method chaining
Example
await middleware
.runner()
.errorHandler((error) => {
console.error("Middleware error:", error);
})
.run((fn, next) => fn(context, next));finalHandler()
finalHandler(finalHandler: FinalHandler): this;Sets a custom final handler to execute when the middleware chain completes successfully.
The final handler is called when the entire middleware pipeline reaches the end by calling next through all handlers. This makes it easier to execute custom logic that is not part of the chain but must run when the chain ends.
Parameters
| Parameter | Type | Description |
|---|---|---|
finalHandler | FinalHandler | The function to execute when the chain completes |
Returns
this
The Runner instance for method chaining
Example
await middleware
.runner()
.finalHandler(() => {
console.log("All middleware completed");
})
.run((fn, next) => fn(context, next));run()
run(cb: Executor<MiddlewareFn>): Promise<void>;Executes the middleware pipeline using the provided executor function.
The executor function is responsible for invoking each middleware handler with the appropriate context and the next callback. Since you control the executor, you can pass any data you want to the middleware.
Parameters
| Parameter | Type | Description |
|---|---|---|
cb | Executor<MiddlewareFn> | The executor function that invokes each middleware handler |
Returns
Promise<void>
A Promise that resolves when the middleware pipeline completes
Example
const context = { user: null };
type MiddlewareFn = (ctx: typeof context, next: NextFn) => void | Promise<void>;
const middleware = new Middleware<MiddlewareFn>();
middleware.add(async (ctx, next) => {
ctx.user = await authenticate();
await next();
});
await middleware.runner().run((fn, next) => fn(context, next));