에러핸들링이나 exception handling은 보통 비즈니스 로직이 작성된 service 파일 안에 작성하며, 이미 nest.js가 제공하는 pre-built in 된 코드들도 존재한다.
- interacting DB
... whenever you're interacting with a database, that's where you might need exception handling.
- Model constraints
예를들어 user를 생성할때 user의 email이 unique 해야하므로 exception handling이 필요하다
- external api
클라이언트가 이미 존재하는 이메일을 보낼때처럼, 유효하지않은 request를 보낼때는 Bad request exception
어떤 이유로 인해 db 연결 자체에서 오류가 날경우는 RequestTimeoutException
를 주로 사용하는듯
public async createUser(createUserDto: CreateUserDto) {
let existingUser = undefined;
try {
existingUser = await this.usersRepository.findOne({
where: { email: createUserDto.email },
});
} catch (error) {
//어떤 이유로 db 연결 실패할경우 statusCode: 408
throw new RequestTimeoutException('Unable to process', {
description: 'Error connecting to the DB',
});
}
// Handle exception
if (existingUser) {
throw new BadRequestException('이미 유저가 존재해요');
//statusCode: 400
}
let newUser = this.usersRepository.create(createUserDto);
newUser = await this.usersRepository.save(newUser);
return newUser;
}
tag가 존재하는 블로그 포스트를 업데이트(수정)하는 service.ts 코드이다.
public async update(patchPostDto: PatchPostDto) {
let tags = undefined;
let post = undefined;
// Find the Tags
try {
tags = await this.tagsService.findMultipleTags(patchPostDto.tags);
} catch (error) {
throw new RequestTimeoutException('db 연동 오류');
}
// Number of tags need to be equal (exeption handling)
// what if no tags were found
// db에 없는 tag + 있는 tag 일시
if (!tags || tags.length! == patchPostDto.tags.length) {
throw new BadRequestException(
'tags id를 다시 체크하고 유효한 id인지 확인해주세요',
);
}
// Find the Post
try {
post = await this.postsRepository.findOneBy({
id: patchPostDto.id,
});
} catch (error) {
throw new RequestTimeoutException('db 연동 오류');
}
if (!post) {
throw new BadRequestException('post id가 존재하지않아요');
}
// Update the properties - TypeORM 에서는 spreadOperator 권장X
post.title = patchPostDto.title ?? post.title;
post.content = patchPostDto.content ?? post.content;
....
// Update the tags
post.tags = tags;
try {
await this.postsRepository.save(post); //update 할떄도 save 메소드를쓴다.
} catch (error) {
throw new RequestTimeoutException('db 연동 오류');
}
return post;
}
throw new HttpException
를 이용해서 custom exception을 만들어보자
첫번째 인자는 client에서 어떤 값을 보여줄지 object를 생성
두번째 인자는 HttpStatus 코드인데, nestjs 내장 코드이다.
세번째 인자는 optional로, client에 보여지지않고 서버 log에만 찍히는 정보
public async test() {
throw new HttpException(
{
status: HttpStatus.MOVED_PERMANENTLY,
error: 'The API endpoint does not exist',
},
HttpStatus.MOVED_PERMANENTLY,
{
description: 'Occured cuz the endpoint was permanently moved',
},
);
}
test()가 실행되면
{
"status": 301,
"error": "The API endpoint does not exist"
}
이렇게 첫번째 인자처럼 response가 던져진다.