Interceptors
An interceptor is a provider class decorated with the @Interceptor()
decorator.
The class, though, must implement the InterceptorHandler
interface.
The interceptor will provide capabilities of adding extra logic before and after the actual route handler, and also to trap it errors.
@Interceptor()
export class TestControllerInterceptor implements InterceptorHandler {
after<TResult>(
context: Context,
handlerResult: TResult,
): HandlerAfterOptions<TResult> | Promise<HandlerAfterOptions<TResult>> | void | Promise<void> {
console.log('TestControllerInterceptor after', context.response.locals.interceptorTest);
}
before(context: Context): HandlerBeforeOptions | Promise<HandlerBeforeOptions> | void | Promise<void> {
console.log('TestControllerInterceptor before');
context.response.locals.interceptorTest = { test: 'hello' };
}
error<TError>(context: Context, error: HttpException<TError>) {
console.log('TestControllerInterceptor error');
}
}
Interceptors than can be utilized at controller or route level via decorating them with the @Intercept()
decorator.
@Intercept(TestControllerInterceptor)
@Controller('/test')
export class TestController {
constructor(
private readonly httpService: HttpService,
private readonly externalService: ExternalTestService,
private readonly loggerService: LoggerService,
) {}
@Get('/hello-world')
async helloWorld(@Cookie('cookie') cookie: string, @Session() session: any) {
this.loggerService.log({ level: 'info', data: 'Test log from /hello-world' });
return { test: 'hello world', cookie, session };
}
@Intercept(TestRouteInterceptor)
@Get('/external')
async external() {
return { external: await this.externalService.getExternalCall() };
}
@Intercept(TestRouteInterceptor)
@Get('/error')
async error() {
throw new ForbiddenError({ error: { test: 'payload'}, message: 'This is an error'});
}
}