dependency-injectionnestjs

How to make Dependency Injection work for global Exception Filter in NestJS?


I am trying to avoid using app.useGlobalFilters(new AllExceptionsFilter(...));, but I am struggling to make DI inject my custom LoggerService into AllExceptionsFilter.

I have my app module with LoggerModule imported and filter defined like this:

import { APP_FILTER } from '@nestjs/core';
...

@Module({
  imports: [LoggerModule],
  providers: [
    {
      provide: APP_FILTER,
      useClass: AllExceptionsFilter,
    },
  ],
})
export default class AppModule {}

Exception Filter (pretty much the same code as in nest docs):

import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus } from '@nestjs/common';
import LoggerService from '../modules/logger/logger.service';

@Catch()
export default class AllExceptionsFilter implements ExceptionFilter {
  constructor(private readonly loggerService: LoggerService) {}

  catch(exception: Error, host: ArgumentsHost): void {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();

    console.log(this.loggerService);
    // this.loggerService.error(exception);

    const status =
      exception instanceof HttpException ? exception.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR;

    response.status(status).json({
      statusCode: status,
      message: exception.message,
      path: request.url,
    });
  }
}

LoggerModule:

@Global()
@Module({
  providers: [LoggerService],
  exports: [LoggerService],
})
export default class LoggerModule {}

Can you point out what is wrong, and why LoggerService is not injected into my ExceptionFilter?

Documentation reference.


Solution

  • I found out why this didn't work.

    My LoggerService was annotated with: @Injectable({ scope: Scope.REQUEST })

    I assume that because the instance was tied to request, it was already discarded at exception phase. Switching to @Injectable({ scope: Scope.TRANSIENT }) solved the issue.