You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者Едуард Сиволап

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 22:16:17