인프런 커뮤니티 질문&답변

김의중님의 프로필 이미지

작성한 질문수

Slack 클론 코딩[백엔드 with NestJS + TypeORM]

class-validator

ExceptionsHandler 에러가 발생합니다.

작성

·

965

·

수정됨

0

class-transformer 도 같이 설치후 요청을 날려보면 아래와 같은 의도하지 않은 에러미세지가 출력됩니다.

{
    "statusCode": 500,
    "message": "Internal server error"
}

또 동시에 터미널에 아래와 같은 에러 로그가 출력됩니다.

[Nest] 8570  - 2023. 05. 27. 오전 10:48:03   ERROR [ExceptionsHandler] data and salt arguments required
Error: data and salt arguments required
    at Object.hash (/Users/apple/Documents/sideProjects2/sleactNestJS/node_modules/bcrypt/bcrypt.js:137:17)
    at /Users/apple/Documents/sideProjects2/sleactNestJS/node_modules/bcrypt/promises.js:29:12
    at new Promise (<anonymous>)
    at Object.module.exports.promise (/Users/apple/Documents/sideProjects2/sleactNestJS/node_modules/bcrypt/promises.js:20:12)
    at Object.hash (/Users/apple/Documents/sideProjects2/sleactNestJS/node_modules/bcrypt/bcrypt.js:133:25)
    at UsersService.postUsers (/Users/apple/Documents/sideProjects2/sleactNestJS/dist/main.js:426:55)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async UsersController.join (/Users/apple/Documents/sideProjects2/sleactNestJS/dist/main.js:1247:9)

ChatGPT에 문의해보니 bcrypt에러 같다고 하는데, bcrypt는 수정하지 않았고 문제도 없어보입니다.

 

제가 강의를 보며 수정한 코드는 4군데 입니다.

  1. users.service.ts 에 기존 Exception 코드 날리기

async postUsers(email: string, nickname: string, password: string) {
    const user = await this.usersRepository.findOne({ where: { email } });
    if (user) {
      throw new UnauthorizedException('이미 존재하는 사용자입니다');
    }
  1. Users.ts entity에 Validation 추가하기

 @IsEmail()
  @ApiProperty({
    example: 'kim@gmail.com',
    description: '이메일',
  })
  @Column('varchar', { name: 'email', unique: true, length: 30 })
  email: string;

  @IsString()
  @IsNotEmpty()
  @Column('varchar', { name: 'nickname', length: 30 })
  nickname: string;

  @IsString()
  @IsNotEmpty()
  @Column('varchar', { name: 'password', length: 100, select: false })
  password: string;

 

  1. main.ts에 useGlobalPipes 꼽기

app.useGlobalPipes(new ValidationPipe());

 

  1. httpException.filter.ts response status 수정하기

const err = exception.getResponse() as
      | { message: any; statusCode: number }
      | { error: string; statusCode: 400; message: string[] };

    if (typeof err !== 'string' && err.statusCode === 400) {
      return response.status(status).json({
        success: false,
        code: status,
        data: err.message,
      });
    }

    response.status(status).json({
      success: false,
      code: status,
      data: err.message,
    });
  }
}

공식문서도 보았는데, 해결이 안되어서 질문 남깁니다.

답변 1

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

UsersService.postUsers

에 에러가 있다고 나오고 있고, hash에 들어간 데이터가 undefined일 것 같네요.

김의중님의 프로필 이미지
김의중
질문자

그러네요! 문제는 email, password 등을 입력 하지 않았는데, Validation이 작동을 하지 않고 다음 회원가입 로직이 실행되어 생기는 이슈 였네요. 그렇다면 왜 validator 로직이 실행이 안되는걸까요?

  1. class-transformer validator 설치

  2. Users.ts entity에 Validation 추가하기

  3. main.ts에 useGlobalPipes 꼽기

  4. httpException.filter.ts response status 수정하기

이거 외에 혹시 추가로 해야할 작업이 있을까요?

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

유저 컨트롤러쪽을 봐야할것같은데요. 컨트롤러에서 UsersEntity를 사용하고있나요??

김의중님의 프로필 이미지
김의중
질문자

컨트롤러 에서 UsersEntity를 찾는 도중 Github 코드 ch2 폴더 에서 @IsEmail 같은 데코레이터가 join.request.dto.ts 에서 사용중인것을 확인하고 그대로 적용해보니 잘 되네요! 강의 에서는 User.ts 엔티티 에서 Valid 데코레이터가 사용중인것으로 보이는데 혹시 변경된 부분일까요?

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

https://github.com/ZeroCho/sleact/blob/master/nest-typeorm/src/users/users.controller.ts#L42

이런식으로 컨트롤러에 직접적으로 dto나 entity가 연결되어 있어야 validation이 됩니다.