NestJS验证器无法访问数据库及读取'user'属性报错求助
问题:NestJS自定义验证器无法访问Prisma数据库,报错
TypeError: Cannot read properties of undefined (reading 'user') 我尝试在NestJS中实现一个通用的唯一值验证器,用于检查Prisma数据库中是否存在指定记录,但调用时出现上述错误。相关代码如下:
验证器代码
interface UniqueValidatorOptions { model: string; field: string; } @ValidatorConstraint({ name: 'UniqueValidator', async: true }) @Injectable() export class UniqueValidator implements ValidatorConstraintInterface { constructor( @Inject(PrismaService) private readonly prismaService: PrismaService, ) {} async validate(value: any, info: ValidationArguments) { console.log(info); const modelOptions: UniqueValidatorOptions = info.constraints[0]; if (!modelOptions) { throw new Error('Model options are not provided.'); } const { model, field } = modelOptions; try { const result = await this.prismaService[model].findFirst({ where: { [field]: value, }, }); return !result; } catch (e) { console.log(e); return false; } } defaultMessage() { return ErrorsEnum.NOT_FOUND_USER; } }
DTO调用代码
export class UsersBaseDto { @Validate(UniqueValidator, [{ model: 'user', field: 'id' }]) id: number; }
错误原因
报错指向this.prismaService[model].findFirst这一行,本质是this.prismaService为undefined。这是因为自定义验证器使用了@Injectable依赖注入,但class-validator默认无法获取NestJS的依赖注入容器实例,导致PrismaService没有被正确注入;其次可能是验证器未在模块中注册。
修复步骤
1. 在模块中注册验证器
将UniqueValidator和PrismaService添加到对应模块的providers数组中(如果其他模块需要使用,还需导出):
import { Module } from '@nestjs/common'; import { PrismaService } from './prisma.service'; import { UniqueValidator } from './unique.validator'; @Module({ providers: [PrismaService, UniqueValidator], exports: [UniqueValidator], // 跨模块使用时需要导出 }) export class UsersModule {}
2. 配置class-validator使用Nest容器
在项目的main.ts中,调用useContainer让class-validator复用Nest的依赖注入容器,确保自定义验证器能获取到注入的服务:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ValidationPipe, useContainer } from '@nestjs/common'; async function bootstrap() { const app = await NestFactory.create(AppModule); // 让class-validator使用Nest的DI容器 useContainer(app.select(AppModule), { fallbackOnErrors: true }); // 启用全局验证管道 app.useGlobalPipes(new ValidationPipe({ transform: true, whitelist: true, })); await app.listen(3000); } bootstrap();
3. 确认Prisma模型名称匹配
检查Prisma Schema中的模型名称:
- 如果模型定义为
model User { ... },则Prisma生成的Client中对应属性为prisma.user(全小写),你传入的model: 'user'是正确的; - 如果模型是驼峰式命名(如
model AdminUser),则对应属性为prisma.adminUser,需同步调整DTO中传入的model值。
4. 优化错误提示(可选)
当前defaultMessage返回的是固定提示,可改为根据验证参数动态生成:
defaultMessage(info: ValidationArguments) { const { model, field } = info.constraints[0]; return `${field} "${info.value}" 已存在于${model}表中`; }
内容的提问来源于stack exchange,提问作者Едуард Сиволап
相关产品推荐
相关产品推荐

