티스토리 뷰
목표: 커스텀 에러 예외처리를 만들기
throw new NotFoundMarketData()
- 커스텀 에러 메시지를 만든다.
- 커스텀 에러 발생시, 프로젝트가종료되지 않는다.
- 커스텀 에러 발생시, 로그를 남긴다.
문제사항
예외가 발생했을 때, 로그의 기록도 내장예외를 사용했을 때와 달랐다.
커스텀 에러도 내장예외때처럼 사용할 수 있는 방법이 없을까?
- posts-exception.ts
export class EmptyPostPasswordException extends HttpException {
constructor() {
super('비밀번호를 입력해주세요!', HttpStatusCode.BadRequest);
}
}
- posts.service.ts
async createPost(
user: Users,
createPostDto: CreatePostDto,
): Promise<InsertResult> {
if (createPostDto.postType === PostType.PRIVATE_POST) {
const originPassword = createPostDto.postPassword;
if (!originPassword) {
// 커스텀 에러
throw new EmptyPostPasswordException();
}
const isRegex = originPassword.match(PRIVATE_PASSWORD_REGEX);
if (!isRegex){
// 기본 내장 에러
throw new BadRequestException('비밀번호는 6자리 이상이며, 숫자는 최소 1개가 필요합니다.')
};
...
}
- 커스텀 에러가 발생했을 때는 500 에러가 뜬다. 내가 원하는 방향과 다르게 BadRequest 에러가 아닌 500에러가 뜬다.
그리고 에러문구도 '비밀번호를 입력해주세요!' 가 아닌 'Internal Server error' 라는 메시지를 리턴했다.... 🤯
- 내장에러(BadRequestException)을 사용했을 때
(해결과정)
어쩌다 해결을 했다. HttpException을 BadRequest 으로 수정했다.
- post-exceptions.ts
export class EmptyPostPasswordException extends BadRequestException {
constructor() {
super('비밀번호를 입력해주세요!');
}
}
수정후 결과
Next Level....
커스텀 필터를 적용해서 에러를 만들어서 에러를 핸들링하고 싶다.
공식다큐먼트와 다른사람들의 문제해결 방안을 참고해서
에러 핸들링을 해보기로 했다.
exception filter 왜 필요해?
Nest의 내장 예외필터는 인식할 수 없는 에러를 InternalServerErrorException (StatusCode = 500)으로 변환시킨다.
NestJS에서 제공하는 예외필터 이외 직접 예외 필터 레이어를 둬서 사용자가 원하는 대로 예외를 다룰 수 있다.
유저 데이터가 존재하지 않으면, 'Not found Error' 메시지를 보내주는 에러가 아닌
'유저 데이터가 존재하지 않습니다.' 에러메시지를 보내주는 것 처럼
요구사항에 알맞는 예외를 만드는 것을 목표로 하고있다.
- file-paths
📦src
┣ 📂filters
┃ ┣ 📂all-exceptions
┃ ┃ ┗ 📜all-exceptions.filter.ts
┃ ┣ 📂http-exception
┃ ┃ ┗ 📜http-exception.filter.ts
┃ ┗ 📜product-exception.filter.ts
┃
┣ 📂markets
┃ ┣ 📂dto
┃ ┃ ┣ 📜create-market.dto.ts
┃ ┃ ┗ 📜update-market.dto.ts
┃ ┣ 📂entities
┃ ┃ ┗ 📜market.entity.ts
┃ ┣ 📜market-exception.ts
┃ ┣ 📜markets.controller.spec.ts
┃ ┣ 📜markets.controller.ts
┃ ┣ 📜markets.module.ts
┃ ┣ 📜markets.service.spec.ts
┃ ┗ 📜markets.service.ts
┃
┣ 📜app.controller.ts
┣ 📜app.module.ts
┣ 📜app.service.ts
┗ 📜main.ts
(1) http-exception.filter 작성
- 참고: 공식다큐먼트
import {
ArgumentsHost,
Catch,
ExceptionFilter,
HttpException,
HttpStatus,
} from '@nestjs/common';
import { Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const statusCode =
exception instanceof HttpException
? exception.getStatus()
: HttpStatus.INTERNAL_SERVER_ERROR;
response.status(statusCode).json({
statusCode: statusCode,
timestamp: new Date().toISOString(),
path: request.url,
message: exception?.getResponse(),
});
}
}
(2) 전역 스코프에서 에러를 캐치할 수 있도록 설정
- all-exceptions-filter.ts
import { ArgumentsHost, Catch } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
super.catch(exception, host);
}
}
- main.ts
import { ValidationPipe } from '@nestjs/common';
import { HttpAdapterHost, NestFactory } from '@nestjs/core';
import { AllExceptionsFilter } from './filters/all-exceptions/all-exceptions.filter';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './filters/http-exception/http-exception.filter';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const { httpAdapter } = app.get(HttpAdapterHost);
app.useGlobalFilters(new AllExceptionsFilter(httpAdapter));
app.useGlobalPipes(new ValidationPipe());
// HttpExceptionFilter을 전역 스코프에 적용.
app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(3000);
}
bootstrap();
(3) 커스텀 에러
- market-exception.ts
import { HttpException } from '@nestjs/common';
export class MarketCustomException extends HttpException {
constructor(message: string, statusCode: number) {
super(message, statusCode);
}
}
(4) 커스텀 에러를 특정 모듈에 적용
- markets.module.ts
import { Module } from '@nestjs/common';
import { MarketsService } from './markets.service';
import { MarketsController } from './markets.controller';
import { APP_FILTER } from '@nestjs/core';
import { HttpExceptionFilter } from 'src/filters/http-exception/http-exception.filter';
@Module({
controllers: [MarketsController],
providers: [
MarketsService,
// 커스텀 에러필터를 적용한다.
{ provide: APP_FILTER, useClass: HttpExceptionFilter },
],
})
export class MarketsModule {}
(5) 컨트롤러에 적용
...
import { MarketCustomException } from './market-exception';
import { HttpExceptionFilter } from 'src/filters/http-exception/http-exception.filter';
// HttpExceptionFilter 을 컨트롤러에서 적용.
@UseFilters(new HttpExceptionFilter())
@Controller('markets')
export class MarketsController {
constructor(private readonly marketsService: MarketsService) {}
@Post()
create(@Body() createMarketDto: CreateMarketDto) {
// 일부러 커스텀 에러를 발생시켜봤다.
throw new MarketCustomException('커스텀에러', HttpStatus.BAD_REQUEST);
}
...
}
(result) 일부러 커스텀 예외를 발생시켰을 때, 내장에러 호출한것처럼 url, message, statusCode 를 나타낸 결과이다!
[참고]
[Nest.js] Exception filter 적용하기
들어가며 많은 기업들이 Nest.js를 활용해서 서버를 구축하는 것을 알았습니다. 더 나은 개발자가 되기 위해서는 지금부터라도 Nest.js에 대해 기초부터 공부해야겠다고 생각했습니다. 왜 많은 기
overcome-the-limits.tistory.com
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Progamming), FP (Functional Programming), and FRP (Functional Reac
docs.nestjs.com
NestJs Exception Filters: Part 02
Introduction
medium.com
'Backend > 꾸준히 TIL' 카테고리의 다른 글
[NestJS] Repository Pattern 적용시키기 (0) | 2022.11.11 |
---|---|
[NestJS + Logger] Custom Logger 와 winston Logger 적용하기 (0) | 2022.11.09 |
[NestJS+TypeORM] Pagination 처리 (0) | 2022.11.07 |
[Jest+NestJS] Jest 테스트 환경세팅 (0) | 2022.11.05 |
[NestJS + regex] 정규표현식 활용하기 (0) | 2022.11.05 |
- Total
- Today
- Yesterday
- typeORM
- Jekyll
- jest
- Mongoose
- vscode
- IT용어
- OS
- 디지털디톡스
- 나도 할 수 있다
- 스마트폰중독
- 클린아키텍쳐
- TDD
- git
- TypeScript
- nestjs jest
- RDBMS
- 참고
- node.js
- 습관개선
- Nest.js
- 한달독서
- MongoDB
- nestjs
- 갓생살자
- 한달어스
- 미완
- 개발용어
- gem
- MySQL
- 바이트디그리
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |