Interceptors let you run logic before a request reaches a route handler or before an error is returned to the client. In HeronJS, they follow the same idea as the Chain of Responsibility pattern and are designed to work with Express middleware behavior.
Create an interceptor
HeronJS supports two interceptor types:
ExpressInterceptorfor normal request processing.ExpressErrorInterceptorfor centralized error handling.
Use a standard interceptor when you want to inspect or modify the request, response, or control flow before the route handler runs.
import {
ExpressInterceptor,
HttpRequest as Request,
HttpResponse as Response,
Next,
} from '@heronjs/express';
export const CheckHeaderInterceptor: ExpressInterceptor = (
req: Request,
res: Response,
next: Next,
) => {
const apiKey = req.headers['x-api-key'];
if (!apiKey) {
return res.status(400).json({ message: 'Missing x-api-key header' });
}
return next();
};Create an error interceptor
Use ExpressErrorInterceptor when you want to handle application errors in one place.
import {
ExpressErrorInterceptor,
HttpRequest as Request,
HttpResponse as Response,
Next,
} from '@heronjs/express';
export const GlobalApiErrorInterceptor: ExpressErrorInterceptor = (
err: Error,
req: Request,
res: Response,
next: Next,
) => {
return res.status(500).json({
message: err.message || 'Internal server error',
});
};This is useful for formatting errors consistently and avoiding duplicated error handling across controllers.
Apply interceptors to a route
Use @UseInterceptors() to attach one or more interceptors to a route handler.
@UseInterceptors() accepts:
- HeronJS interceptors.
- Third-party Express middleware such as
multer,cors, orhelmet.
import { Post, Request, Rest, UseInterceptors } from '@heronjs/common';
import { HttpRequest } from '@heronjs/express';
import { CheckHeaderInterceptor } from '../interceptors/check-header.interceptor';
@Rest('/todos')
export class TodosRest {
@Post({ uri: '/upload' })
@UseInterceptors([CheckHeaderInterceptor])
public async uploadFile(@Request() request: HttpRequest): Promise<any> {
return {
body: request.body,
};
}
}Use third-party middleware with interceptors
Because HeronJS supports Express middleware, you can combine built-in interceptors with packages such as multer .
import { Post, Request, Rest, UseInterceptors } from '@heronjs/common';
import { HttpRequest } from '@heronjs/express';
import multer from 'multer';
import { CheckHeaderInterceptor } from '../interceptors/check-header.interceptor';
const upload = multer({ dest: 'uploads/' });
@Rest('/todos')
export class TodosRest {
@Post({ uri: '/upload' })
@UseInterceptors([CheckHeaderInterceptor, upload.single('file')])
public async uploadFile(@Request() request: HttpRequest): Promise<any> {
return {
body: request.body,
file: request.file,
};
}
}This pattern is useful when you need request validation, authentication checks, logging, or file upload behavior before the main route logic executes.