我在typeORM实体字段电子邮件中设置了自定义唯一验证器装饰器。 Nestjs有依赖注入,但服务没有注入。
错误是:TypeError:无法读取未定义的属性'findByEmail'
有关实施自定义电子邮件验证工具的任何帮助吗?
user.entity.ts
@Column()
@Validate(CustomEmail, {
message: "Title is too short or long!"
})
@IsEmail()
email: string;
我的CustomEmail验证程序是
import {ValidatorConstraint, ValidatorConstraintInterface,
ValidationArguments} from "class-validator";
import {UserService} from "./user.service";
@ValidatorConstraint({ name: "customText", async: true })
export class CustomEmail implements ValidatorConstraintInterface {
constructor(private userService: UserService) {}
async validate(text: string, args: ValidationArguments) {
const user = await this.userService.findByEmail(text);
return !user;
}
defaultMessage(args: ValidationArguments) {
return "Text ($value) is too short or too long!";
}
}
我知道我可以在列选项中设置唯一
@Column({
unique: true
})
但是这会抛出一个mysql错误和ExceptionsHandler崩溃我的应用程序,所以我自己无法处理它......
Thankx!
答案 0 :(得分:6)
我可以在这里提出两种不同的方法,第一种在没有额外请求的情况下在本地捕获约束违规错误,第二种使用全局错误过滤器,在整个应用程序中捕获此类错误。我个人使用后者。
无需进行额外的数据库请求。您可以捕获违反唯一约束的错误并向客户端抛出您想要的任何 HttpException
。在users.service.ts
:
public create(newUser: Partial<UserEntity>): Promise<UserEntity> {
return this.usersRepository.save(newUser).catch((e) => {
if (/(email)[\s\S]+(already exists)/.test(e.detail)) {
throw new BadRequestException(
'Account with this email already exists.',
);
}
return e;
});
}
哪个会返回:
甚至创建一个全局的QueryErrorFilter:
@Catch(QueryFailedError)
export class QueryErrorFilter extends BaseExceptionFilter {
public catch(exception: any, host: ArgumentsHost): any {
const detail = exception.detail;
if (typeof detail === 'string' && detail.includes('already exists')) {
const messageStart = exception.table.split('_').join(' ') + ' with';
throw new BadRequestException(
exception.detail.replace('Key', messageStart),
);
}
return super.catch(exception, host);
}
}
然后在 main.ts
中:
async function bootstrap() {
const app = await NestFactory.create(/**/);
/* ... */
const { httpAdapter } = app.get(HttpAdapterHost);
app.useGlobalFilters(new QueryErrorFilter(httpAdapter));
/* ... */
await app.listen(3000);
}
bootstrap();
这将给出通用的 $table entity with ($field)=($value) already exists.
错误消息。示例:
答案 1 :(得分:1)
我修改了我的代码。我正在检查用户服务(而不是自定义验证器)中用户名/电子邮件的唯一性,并在用户已插入数据库时返回HttpExcetion。