Nest.js无参数方法调用失败问题排查与解决
NestJS控制器无参数方法报错问题排查与解决
问题现象
以下控制器方法可正常运行:
@ApiOkResponse({ type: Bird, }) @Get('demoBird') // eslint-disable-next-line @typescript-eslint/no-unused-vars async demo(@Query('dummy') _dummy: string) { this.logger.log('findDemoBird'); return this.service.findDemoBird(); }
但移除其中的@Query('dummy') _dummy: string参数声明后,调用接口会抛出如下错误:
error Application: Cannot read properties of undefined (reading 'findDemoBird')
项目中其他控制器的无参数方法均可正常执行,核心依赖版本如下:
"@nestjs/core": "^9.0.0", "ts-jest": "28.0.8", "ts-loader": "^9.2.3", "ts-node": "^10.0.0", "tsconfig-paths": "4.1.0", "typescript": "^4.7.4"
控制器完整代码
import { Body, Controller, Delete, Get, Inject, Param, Patch, Post, Put, Query, } from '@nestjs/common'; import { UpdateBirdDto } from './dtos/update-bird.dto'; import { BirdService } from './bird.service'; import { TraceableLogger } from 'src/common/logger/TraceableLogger'; import { Bird } from './bird.schema'; import { ApiTags, ApiOperation, ApiParam, ApiOkResponse, ApiExtraModels, ApiNotFoundResponse, ApiInternalServerErrorResponse, getSchemaPath, ApiQuery, ApiBody, } from '@nestjs/swagger'; import { Subscription } from 'src/billing/subscription/subscription.schema'; import { UpdateLoansGdprDto } from '../loan/dtos/update-loans-gdpr.dto'; @Controller('birds') export class BirdController { constructor( @Inject('BirdLogger') private readonly logger: TraceableLogger, private readonly service: BirdService, ) { this.logger.setContext(BirdController.name); } }
解决方案
注释掉BirdService构造函数中的@Inject(forwardRef(() => SubscriptionService))装饰器后,问题得到解决:
@Injectable() export class BirdService { constructor( private readonly repository: BirdRepository, //// @Inject(forwardRef(() => SubscriptionService)) private readonly subscriptionService: SubscriptionService, private readonly autoService: CarService, private readonly katzenService: CatService, @Inject('BirdLogger') private readonly logger: TraceableLogger, ) { this.logger.setContext(PracticeService.name); } }
补充SubscriptionService构造代码
@Injectable() export class SubscriptionService { private schemaFields: string; private readonly logger = new Logger(SubscriptionService.name); constructor( @InjectModel(Subscription.name, 'birds') private readonly model: Model<Subscription>, private readonly configService: ConfigService, ) { this.schemaFields = Object.keys(SubscriptionSchema.paths).join(' '); } }
内容的提问来源于stack exchange,提问作者DraganS
相关产品推荐
相关产品推荐

