How do I use database entities in middleware? - node.js

// location.entity.ts
import {Entity, Column, PrimaryGeneratedColumn, CreateDateColumn} from 'typeorm'
#Entity('location')
export class Location {
#PrimaryGeneratedColumn()
id: number;
#Column({length: 500})
name: string;
#Column('text')
desc: string;
#CreateDateColumn({type: 'timestamp'})
date: number;
}
// black.middleware.ts
import {Injectable, NestMiddleware} from '#nestjs/common'
import {Response, Request} from 'express'
import {InjectRepository} from '#nestjs/typeorm'
import {Location} from 'src/location/location.entity'
import {Repository} from 'typeorm'
#Injectable()
export class BlackMiddleware implements NestMiddleware {
constructor(#InjectRepository(Location) private locationRepository: Repository<Location>) {
}
use(req: Request, res: Response, next: () => void): any {
console.log(this.locationRepository, 'aaa');
return true;
}
}
In middleware, I want to use some other dependency injection, either entity, so how do I refer to it correctly?
// app.module.ts
...
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer): any {
consumer.apply(BlackMiddleware).forRoutes('*')
}
}
Expect typeorm to be used in the middleware, but I don't know how to resolve the dependency. Is the middleware being used globally
If used in this way, an error will be reported:
[Nest] 56559 - 2020/12/25 上午11:43:08 [ExceptionHandler] Nest can't resolve dependencies of the BlackMiddleware (?). Please make sure that the argument LocationRepository at index [0] is available in the BlackMiddleware context.
Potential solutions:
- If LocationRepository is a provider, is it part of the current BlackMiddleware?
- If LocationRepository is exported from a separate #Module, is that module imported within BlackMiddleware?
#Module({
imports: [ /* the Module containing LocationRepository */ ]
})
+0ms
Error: Nest can't resolve dependencies of the BlackMiddleware (?). Please make sure that the argument LocationRepository at index [0] is available in the BlackMiddleware context.
Potential solutions:
- If LocationRepository is a provider, is it part of the current BlackMiddleware?
- If LocationRepository is exported from a separate #Module, is that module imported within BlackMiddleware?
#Module({
imports: [ /* the Module containing LocationRepository */ ]
})
at Injector.lookupComponentInParentModules (/Users/brian/code/node/nest/learn-nest/node_modules/#nestjs/core/injector/injector.js:192:19)
at async Injector.resolveComponentInstance (/Users/brian/code/node/nest/learn-nest/node_modules/#nestjs/core/injector/injector.js:148:33)
at async resolveParam (/Users/brian/code/node/nest/learn-nest/node_modules/#nestjs/core/injector/injector.js:102:38)
at async Promise.all (index 0)
at async Injector.resolveConstructorParams (/Users/brian/code/node/nest/learn-nest/node_modules/#nestjs/core/injector/injector.js:117:27)
at async Injector.loadInstance (/Users/brian/code/node/nest/learn-nest/node_modules/#nestjs/core/injector/injector.js:81:9)
at async Injector.loadProvider (/Users/brian/code/node/nest/learn-nest/node_modules/#nestjs/core/injector/injector.js:38:9)
at async Promise.all (index 0)
at async InstanceLoader.createInstancesOfProviders (/Users/brian/code/node/nest/learn-nest/node_modules/#nestjs/core/injector/instance-loader.js:43:9)
at async /Users/brian/code/node/nest/learn-nest/node_modules/#nestjs/core/injector/instance-loader.js:28:13
at async Promise.all (index 26)
at async InstanceLoader.createInstances (/Users/brian/code/node/nest/learn-nest/node_modules/#nestjs/core/injector/instance-loader.js:27:9)
at async InstanceLoader.createInstancesOfDependencies (/Users/brian/code/node/nest/learn-nest/node_modules/#nestjs/core/injector/instance-loader.js:17:9)
at async /Users/brian/code/node/nest/learn-nest/node_modules/#nestjs/core/nest-factory.js:90:17
at async Function.asyncRun (/Users/brian/code/node/nest/learn-nest/node_modules/#nestjs/core/errors/exceptions-zone.js:18:13)
at async NestFactoryStatic.initialize (/Users/brian/code/node/nest/learn-nest/node_modules/#nestjs/core/nest-factory.js:88:13)
How do I properly use other dependency injection (such as database) in middleware?

Maybe you could try service just like controller. Let the logic be handled at the service layer.
for example:
import { Injectable, Logger, NestMiddleware } from '#nestjs/common';
import { NextFunction, Request, Response } from 'express';
import * as requestIp from 'request-ip';
import { LoggerService } from 'src/logger/logger.service';
#Injectable()
export class HttpLoggerMiddleware implements NestMiddleware {
constructor(private readonly loggerService: LoggerService) {}
private logger = new Logger();
use(request: Request, response: Response, next: NextFunction): void {
const { ip, method, originalUrl } = request;
const clientIp = requestIp.getClientIp(request);
const msg = `${method} ${originalUrl} ${clientIp} ${ip} `;
this.logger.log(msg);
this.loggerService.create({
ip: clientIp,
originalUrl,
});
next();
}
}

Related

Trying to use in Nestjs Custom Repository typeorm

by example:
[https://stackoverflow.com/questions/72549668/how-to-do-custom-repository-using-typeorm-mongodb-in-nestjs][1]
Created custom repository в yandex-ndd-api-client.module:
import { DataSource, Repository } from 'typeorm';
import { Injectable } from '#nestjs/common';
// import {Team} from '#Domain/Team/Models/team.entity';
import { TestRepositoryTypeorm } from '../entity/testRepositoryTypeorm.entity';
#Injectable()
export class TestRepository extends Repository<TestRepositoryTypeorm> {
constructor(private dataSource: DataSource) {
super(TestRepositoryTypeorm, dataSource.createEntityManager());
}
async findTest(): Promise<any> { //TestRepositoryTypeorm | undefined
const findTests = await this.dataSource
.getRepository(TestRepositoryTypeorm)
.createQueryBuilder('test')
.getMany();
return await findTests;
}
}
Connected in the module::
providers: [YandexDeliveryService, YandexNddApiClientService, ConfigService, SyncService, TestRepository],
Connected it to the service yandex-ndd-api-client.service:
import { TestRepository } from './repository/testRepositoryTypeorm.retository';
#Injectable()
export class YandexNddApiClientService {
constructor(
// private yandexDeliveryApiService: YandexDeliveryApiService,
private httpService: HttpService,
private dataSource: DataSource,
private configService: ConfigService,
#Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
// #InjectRepository(TestRepository)
private testRepository: TestRepository,
) {}
Called in service:
//testRepositoryTypeorm
async testRepositoryTypeorm(): Promise<any> {
try {
console.log('testRepositoryTypeorm');
// return 'testRepositoryTypeorm';
return await this.testRepository.findTest();
} catch (e) {
console.log('ERROR testRepositoryTypeorm:', e);
}
}
As a result:
ERROR [ExceptionHandler] Nest can't resolve dependencies of the YandexNddApiClientService (HttpService, DataSource, ConfigService, winston, ?, SchedulerRegistry). Please make sure that the argument TestRepository at index [4] is available in the DetmirApiClientModule context.
Potential solutions:
- If TestRepository is a provider, is it part of the current DetmirApiClientModule?
- If TestRepository is exported from a separate #Module, is that module imported within DetmirApiClientModule?
#Module({
imports: [ /* the Module containing TestRepository */ ]
})
[1]: https://stackoverflow.com/questions/72549668/how-to-do-custom-repository-using-typeorm-mongodb-in-nestjs
DetmirApiClientModule.ts:
import { Module } from '#nestjs/common';
import { DetmirApiClientService } from './detmir-api-client.service';
import { DetmirApiClientController } from './detmir-api-client.controller';
import { SyncService } from 'src/sync.service';
import { YandexNddApiClientService } from 'src/yandex-ndd-api-client/yandex-ndd-api-client.service';
import { HttpModule, HttpService } from '#nestjs/axios';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { YandexNddApiClientModule } from 'src/yandex-ndd-api-client/yandex-ndd-api-client.module';
#Module({
providers: [DetmirApiClientService, SyncService, YandexNddApiClientService],
controllers: [DetmirApiClientController],
imports: [HttpModule, YandexNddApiClientModule], //TestRepository
})
export class DetmirApiClientModule {}
Most likely your YandexNddApiClientModule does not add the YandexNddApiClientService to the exports array. Add YandexNddApiClientService to the exports if it is not already there and remove YandexNddApiClientService from the providers array of DetmirApiClientModule. The error is being raised because you have YandexNddApiClientService declared in the providers of DetmirApiClientModule so Nest is trying to create the provider in the new module rather than re-use the module from its original context

How to get name of module, which controller processing request?

I want to get name of module, which controller processing request.
#Get('/')
getIndex() {
console.log('name of module');
}
I don't know exactly the purpose behind your question, but I'll leave you some alternatives.
First one and the dirtier. You can get the instance of the module that your productController is imported by finding it into the modules container.
import { Controller, Get, Query } from '#nestjs/common';
import { ModulesContainer } from '#nestjs/core';
import { Module } from '#nestjs/core/injector/module';
#Controller('path')
export class ProductController {
constructor(
private modulesContainer: ModulesContainer,
private productService: ProductService
) { }
#Get()
findAll(#Query() dto: any) {
let yourModule: Module;
this.modulesContainer.forEach((v) => {
if(v.controllers.has(this.constructor.name)) { // in this condition, you will find your module based in the imports from it, if your controller is importe in some module it will get the module and put in "yourModule" variable.
// Here
yourModule= v;
}
});
console.log(yourModule);
return this.productService.findAll();
}
}
And for a cleaner approach you can get the moduleRef in your controller
import { Controller, Get, Query } from '#nestjs/common';
import { ModuleRef} from '#nestjs/core';
#Controller('path')
export class ProductController {
constructor(
private moduleRef: ModuleRef,
private productService: ProductService
) { }
#Get()
findAll(#Query() dto: any) {
console.log(this.moduleRef) //your module ref
return this.productService.findAll();
}
}
But of course depends on what's you're trying to do.

how to unit test a class extending an abstract class reading environment variables

I want to get into unit testing and have some configuration services for my Nest API that I want to test. When starting the application I validate the environment variables with the joi package.
I have multiple configuration services for the database, the server, ... so I created a base service first. This one is able to read environment variables, parse the raw string to a desired datatype and validate the value.
import { ConfigService } from '#nestjs/config';
import { AnySchema, ValidationResult, ValidationError } from '#hapi/joi';
export abstract class BaseConfigurationService {
constructor(protected readonly configService: ConfigService) {}
protected constructValue(key: string, validator: AnySchema): string {
const rawValue: string = this.configService.get(key);
this.validateValue(rawValue, validator, key);
return rawValue;
}
protected constructAndParseValue<TResult>(key: string, validator: AnySchema, parser: (value: string) => TResult): TResult {
const rawValue: string = this.configService.get(key);
const parsedValue: TResult = parser(rawValue);
this.validateValue(parsedValue, validator, key);
return parsedValue;
}
private validateValue<TValue>(value: TValue, validator: AnySchema, label: string): void {
const validationSchema: AnySchema = validator.label(label);
const validationResult: ValidationResult = validationSchema.validate(value);
const validationError: ValidationError = validationResult.error;
if (validationError) {
throw validationError;
}
}
}
Now I can extend this service with multiple configuration services. For the sake of simplicity I will take the server configuration service for this. Currently it only holds the port the application will listen to.
import { Injectable } from '#nestjs/common';
import { ConfigService } from '#nestjs/config';
import * as Joi from '#hapi/joi';
import { BaseConfigurationService } from './base.configuration.service';
#Injectable()
export class ServerConfigurationService extends BaseConfigurationService {
public readonly port: number;
constructor(protected readonly configService: ConfigService) {
super(configService);
this.port = this.constructAndParseValue<number>(
'SERVER_PORT',
Joi.number().port().required(),
Number
);
}
}
I found multiple articles out there that I should only test public methods, e.g.
https://softwareengineering.stackexchange.com/questions/100959/how-do-you-unit-test-private-methods
so I'm assuming I should not test the methods from the base configuration service. But I would like to test the classes extending the base service. I started with this
import { Test, TestingModule } from '#nestjs/testing';
import { ConfigService } from '#nestjs/config';
import { ServerConfigurationService } from './server.configuration.service';
const mockConfigService = () => ({
get: jest.fn(),
});
describe('ServerConfigurationService', () => {
let serverConfigurationService: ServerConfigurationService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
ServerConfigurationService,
{
provide: ConfigService,
useFactory: mockConfigService
}
],
}).compile();
serverConfigurationService = module.get<ServerConfigurationService>(ServerConfigurationService);
});
it('should be defined', () => {
expect(serverConfigurationService).toBeDefined();
});
});
but as you can see in the second code snippet I'm calling the functions from the base service in the constructor. The test instantly fails with
ValidationError: "SERVER_PORT" must be a number
Is there a way I can unit test the configuration services although they depend on an abstract base class and an external .env file? Because I know I can create a mockConfigService but I think the base class breaks this. I don't know how to fix this test file.
The main problem boils down to this: You are using the Joi libary to parse environment variables. Whenever you call validateValue, Joi functions are called that expect actual environment variables to be set (in this case, SERVER_PORT). Now that these environment variables need to be set is a valid assumption for the running service. But in your test cases, you have no environment variables set, hence the Joi validation fails.
A primitive solution would be to set process.env.SERVER_PORT to some value in your beforeEach and delete it in afterEach. However, this is just a work-around around the actual issue.
The actual issue is: You hard-coded library calls into your BaseConfigurationService that have the assumption that environment variables are set. We already figured out earlier that this is not a valid assumption when running tests. When you stumble upon issues like this when writing tests, it often points to a problem of tight coupeling.
How can we address that?
We can separate the concerns clearly and abstract away the actual validation into its own service class that's used by BaseConfigurationService. Let's call that service class ValidationService.
We can then inject that service class into BaseConfigurationService using Nest's dependency injection.
When running tests, we can mock the ValidationService so it does not rely on actual environment variables, but, for example, just doesn't complain about anything during validation.
So here's how we can achieve that, step by step:
1. Define a ValidationService interface
The interface simply describes how a class needs to look that can validate values:
import { AnySchema } from '#hapi/joi';
export interface ValidationService {
validateValue<TValue>(value: TValue, validator: AnySchema, label: string): void;
}
2. Implement the ValidationService
Now we'll take the validation code from your BaseConfigurationService and use it to implemente ValidationService:
import { Injectable } from '#nestjs/common';
import { AnySchema, ValidationResult, ValidationError } from '#hapi/joi';
#Injectable()
export class ValidationServiceImpl implements ValidationService {
validateValue<TValue>(value: TValue, validator: AnySchema, label: string): void {
const validationSchema: AnySchema = validator.label(label);
const validationResult: ValidationResult = validationSchema.validate(value);
const validationError: ValidationError = validationResult.error;
if (validationError) {
throw validationError;
}
}
}
3. Inject ValidationServiceImpl into BaseConfigurationService
We'll now remove the validation logic from the BaseConfigurationService and instead add a call to ValidationService:
import { ConfigService } from '#nestjs/config';
import { AnySchema, ValidationResult, ValidationError } from '#hapi/joi';
import { ValidationServiceImpl } from './validation.service.impl';
export abstract class BaseConfigurationService {
constructor(protected readonly configService: ConfigService,
protected readonly validationService: ValidationServiceImpl) {}
protected constructValue(key: string, validator: AnySchema): string {
const rawValue: string = this.configService.get(key);
this.validationService.validateValue(rawValue, validator, key);
return rawValue;
}
protected constructAndParseValue<TResult>(key: string, validator: AnySchema, parser: (value: string) => TResult): TResult {
const rawValue: string = this.configService.get(key);
const parsedValue: TResult = parser(rawValue);
this.validationService.validateValue(parsedValue, validator, key);
return parsedValue;
}
}
4. Implemente a mock ValidationService
For testing purposes, we don't want to validate against actual environment variables, but just genereally accept all values. So we implement a mock service:
import { ValidationService } from './validation.service';
import { AnySchema, ValidationResult, ValidationError } from '#hapi/joi';
export class ValidationMockService implements ValidationService{
validateValue<TValue>(value: TValue, validator: AnySchema, label: string): void {
return;
}
}
5. Adapt classes extending BaseConfigurationService to have ConfigurationServiceImpl injected and pass it on to BaseConfigurationService:
import { Injectable } from '#nestjs/common';
import { ConfigService } from '#nestjs/config';
import * as Joi from '#hapi/joi';
import { BaseConfigurationService } from './base.configuration.service';
import { ValidationServiceImpl } from './validation.service.impl';
#Injectable()
export class ServerConfigurationService extends BaseConfigurationService {
public readonly port: number;
constructor(protected readonly configService: ConfigService,
protected readonly validationService: ValidationServiceImpl) {
super(configService, validationService);
this.port = this.constructAndParseValue<number>(
'SERVER_PORT',
Joi.number().port().required(),
Number
);
}
}
6. use the mock service in the test
Finally, now that ValidationServiceImpl is a dependency of BaseConfigurationService, we use the mocked version in the test:
import { Test, TestingModule } from '#nestjs/testing';
import { ConfigService } from '#nestjs/config';
import { ServerConfigurationService } from './server.configuration.service';
import { ValidationServiceImpl } from './validation.service.impl';
import { ValidationMockService } from './validation.mock-service';
const mockConfigService = () => ({
get: jest.fn(),
});
describe('ServerConfigurationService', () => {
let serverConfigurationService: ServerConfigurationService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
ServerConfigurationService,
{
provide: ConfigService,
useFactory: mockConfigService
},
{
provide: ValidationServiceImpl,
useClass: ValidationMockService
},
],
}).compile();
serverConfigurationService = module.get<ServerConfigurationService>(ServerConfigurationService);
});
it('should be defined', () => {
expect(serverConfigurationService).toBeDefined();
});
});
Now when running the tests, ValidationMockService will be used. Plus, apart from fixing your test, you also have a clean separation of concerns.
The refactoring I provided here is just an example how you can go ahead. I guess that, depending on your further use cases, you might cut ValidationService differently than I did, or even separate more concerns into new service classes.

How To Mock Repository, Service and Controller In NestJS (Typeorm & Jest)

I'm new at typescript. My Nestjs project app is something like this. I'm trying to use repository pattern, so i separated business logic (service) and persistance logic (repository)
UserRepository
import { Injectable } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
import { UserEntity } from './entities/user.entity';
#Injectable()
export class UserRepo {
constructor(#InjectRepository(UserEntity) private readonly repo: Repository<UserEntity>) {}
public find(): Promise<UserEntity[]> {
return this.repo.find();
}
}
UserService
import { Injectable } from '#nestjs/common';
import { UserRepo } from './user.repository';
#Injectable()
export class UserService {
constructor(private readonly userRepo: UserRepo) {}
public async get() {
return this.userRepo.find();
}
}
UserController
import { Controller, Get } from '#nestjs/common';
import { UserService } from './user.service';
#Controller('/users')
export class UserController {
constructor(private readonly userService: UserService) {}
// others method //
#Get()
public async getUsers() {
try {
const payload = this.userService.get();
return this.Ok(payload);
} catch (err) {
return this.InternalServerError(err);
}
}
}
How do i create unit testing for repository, service & controller without actually persist or retrieve data to DB (using mock)?
Mocking in NestJS is pretty easily obtainable using the testing tools Nest exposes is #nestjs/testing. In short, you'll want to create a Custom Provider for the dependency you are looking to mock, and that's all there is. However, it's always better to see an example, so here is a possibility of a mock for the controller:
describe('UserController', () => {
let controller: UserController;
let service: UserService;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
controllers: [UserController],
providers: [
{
provide: UserService,
useValue: {
get: jest.fn(() => mockUserEntity) // really it can be anything, but the closer to your actual logic the better
}
}
]
}).compile();
controller = moduleRef.get(UserController);
service = moduleRef.get(UserService);
});
});
And from there you can go on and write your tests. This is pretty much the same set up for all tests using Nest's DI system, the only thing to be aware of is things like #InjectRepository() and #InjectModel() (Mongoose and Sequilize decorators) where you'll need to use getRepositoryToken() or getModelToken() for the injection token. If you're looking for more exmaples take a look at this repository

NestJS How to add custom Logger to custom ExceptionFilter

I am using NestJS 5.4.0
I have custom LoggerService, it's working perfectly. But, how can I add this LoggerService to ExceptionFilter.
// logger.service.ts
import {Injectable, LoggerService} from '#nestjs/common';
#Injectable()
export class Logger implements LoggerService {
log(message: string) {
console.log(message);
}
error(message: string, trace: string) {
console.error(message);
}
warn(message: string) {
console.warn(message);
}
}
//logger.module.ts
import { Module } from '#nestjs/common';
import {Logger} from '../services/logger.service';
#Module({
providers: [Logger],
exports: [Logger],
})
export class LoggerModule {}
// user.module.ts
import { Module } from '#nestjs/common';
import {UserService} from '../services/user.service';
import {LoggerModule} from './logger.module';
#Module({
imports: [LoggerModule],
providers: [UserService],
exports: [UserService],
})
export class UserModule {}
It's working perfectly.
import {Logger} from './logger.service';
export class UserService {
constructor(
private logger: Logger
) {}
private test = () => {
this.logger.log("test"); // log success "test" to console
}
}
But how can I add my custom Logger to ExceptionFilter
// forbidden.exception.filter.ts
import {HttpException, HttpStatus, Injectable} from '#nestjs/common';
#Injectable()
export class ForbiddenException extends HttpException {
constructor(message?: string) {
super(message || 'Forbidden', HttpStatus.FORBIDDEN);
// I want to add my custom logger here!
}
}
Thank for reading.
First of all your class ForbiddenException extends HttpException is not
what it calls ExceptionFilter. ExceptionFilter is
exceptions layer which is responsible for processing all unhandled exceptions across an application
docs
You provided exmaple when you are trying to inject it to your custom HttpException. But thats wrong. Your exception don't have to be responsible for logging. Thats what ExceptionFilter should be responsible for.
Anyway, for now (17 oct 2019) there is no example in official docs how to inject providers to ExceptionFilter.
You can pass it to constructor on init, but you should to get Logger instance before with app.get<T>(...) method.
For example I've changed code from exception-filters docs:
// HttpExceptionFilter.ts
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '#nestjs/common';
import { Request, Response } from 'express';
import {MyLogger} from '../MyLogger'
#Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
constructor(private readonly logger: MyLogger) {}
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
if (status >= 500) {
this.logger.error({ request, response });
}
response
.status(status)
.json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
});
}
}
and bootstrap.ts code:
// bootstrap.ts
const app = await NestFactory.create(MainModule, {
logger: false,
});
const logger = app.get<MyLogger>(MyLogger);
app.useLogger(logger);
app.useGlobalFilters(new HttpExceptionFilter(logger));
This technique can be used for all this INestApplication methods:
app.useGlobalFilters
app.useGlobalGuards
app.useGlobalInterceptors
app.useGlobalPipes
app.useLogger
app.useWebSocketAdapter
First of all, to use dependency injection with Exception filters you cannot register them using the useGlobalFilters() method:
const app = await NestFactory.create(MainModule, {
logger: false,
});
const logger = app.get<MyLogger>(MyLogger);
app.useLogger(logger);
//Remove this line
//app.useGlobalFilters(new HttpExceptionFilter(logger));
Next in your MainModule, add your custom exception filter as a provider (note: filters are automatically set as global no matter what module you add them to but as a best practice, add them to your top level module):
import { Module } from '#nestjs/common';
import { APP_FILTER } from '#nestjs/core';
import { LoggerModule } from './logger.module';
import { ForbiddenException } from './forbidden.exception.filter.ts';
#Module({
imports: [
LoggerModule //this is your logger module
],
providers: [
{
provide: APP_FILTER, //you have to use this custom provider
useClass: ForbiddenException //this is your custom exception filter
}
]
})
export class MainModule {}
Now you can inject the logger into your custom exception filter:
import {HttpException, HttpStatus, Injectable} from '#nestjs/common';
import { Logger } from './path/to/logger';
#Injectable()
export class ForbiddenException extends HttpException {
constructor(private logger: Logger) {}
catch(exception: HttpException, response) {
this.logger.log('test');
}
}
Pseudo code but I think you get the idea.

Resources