예외 필터
Nest에는 애플리케이션 전체에서 처리되지 않은 모든 예외를 처리하는 예외 레이어 가 내장되어 있습니다. 애플리케이션 코드에서 예외를 처리하지 않으면 이 계층에서 예외를 포착한 다음 자동으로 적절한 사용자 친화적인 응답을 보냅니다.
표준 예외 던지기
Nest는 패키지 HttpException에서 노출되는 내장 클래스를 제공합니다. @nestjs/common일반적인 HTTP REST/GraphQL API 기반 응용 프로그램의 경우 특정 오류 조건이 발생할 때 표준 HTTP 응답 개체를 보내는 것이 가장 좋습니다.
예를 들어, CatsController에는 findAll()메소드( GET라우트 핸들러)가 있습니다. 이 라우트 핸들러가 어떤 이유로 예외를 던졌다고 가정해 봅시다. 이를 시연하기 위해 다음과 같이 하드 코딩합니다.
@Get()
async findAll() {
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
클라이언트가 이 끝점을 호출할 때 응답은 다음과 같습니다.
{
"statusCode": 403,
"message": "Forbidden"
}
HttpException생성자는 응답을 결정하는 두 개의 필수 인수를 취합니다 .
- response인수는 JSON 응답 본문을 정의합니다 . string 또는 object아래에 설명된 대로 일 수 있습니다 .
- status인수는 HTTP 상태 코드를 정의합니다 .
기본적으로 JSON 응답 본문에는 두 가지 속성이 포함됩니다.
- statusCodestatus: 기본값은 인수 에 제공된 HTTP 상태 코드입니다.
- message: HTTP 오류에 대한 간략한 설명status
JSON 응답 본문의 메시지 부분만 재정의하려면 response인수에 문자열을 제공합니다. 전체 JSON 응답 본문을 재정의하려면 response인수에 개체를 전달합니다. Nest는 객체를 직렬화하고 JSON 응답 본문으로 반환합니다.
두 번째 생성자 인수 - status-는 유효한 HTTP 상태 코드여야 합니다. 모범 사례는 에서 HttpStatus가져온 열거형 을 사용하는 것 @nestjs/common입니다.
다음은 전체 응답 본문을 재정의하는 예입니다.
@Get()
async findAll() {
throw new HttpException({
status: HttpStatus.FORBIDDEN,
error: 'This is a custom message',
}, HttpStatus.FORBIDDEN);
}
위를 사용하면 응답이 다음과 같이 표시됩니다.
{
"status": 403,
"error": "This is a custom message"
}
사용자 정의 예외
대부분의 경우 사용자 지정 예외를 작성할 필요가 없으며 다음 섹션에 설명된 대로 기본 제공 Nest HTTP 예외를 사용할 수 있습니다. 사용자 지정 예외를 만들어야 하는 경우 사용자 지정 예외가 기본 클래스 에서 상속되는 고유한 예외 계층 을 만드는 것이 좋습니다.HttpException이 접근 방식을 사용하면 Nest가 예외를 인식하고 자동으로 오류 응답을 처리합니다. 이러한 사용자 정의 예외를 구현해 보겠습니다.
export class ForbiddenException extends HttpException {
constructor() {
super('Forbidden', HttpStatus.FORBIDDEN);
}
}
ForbiddenExceptionextends base 이므로 HttpException내장 예외 처리기와 원활하게 작동하므로 findAll()메서드 내에서 사용할 수 있습니다.
@Get()
async findAll() {
throw new ForbiddenException();
}
예외 필터
기본(내장) 예외 필터가 자동으로 많은 경우를 처리할 수 있지만 예외 레이어를 완전히 제어 할 수 있습니다. 예를 들어, 일부 동적 요소를 기반으로 로깅을 추가하거나 다른 JSON 스키마를 사용할 수 있습니다. 예외 필터 는 정확히 이러한 목적을 위해 설계되었습니다. 이를 통해 정확한 제어 흐름과 클라이언트로 다시 전송되는 응답 내용을 제어할 수 있습니다.
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Request, 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 status = exception.getStatus();
const error = exception.getResponse() as
| string
| { error: string; statusCode: number; message: string | string[] };
if (typeof error === 'string') {
response.status(status).json({
success: false,
timestamp: new Date().toISOString(),
path: request.url,
error,
});
} else {
response.status(status).json({
success: false,
timestamp: new Date().toISOString(),
...error,
});
}
}
}
예외 필터를 만들고
// cats/
@Get()
@UseFilters
getAllCat() {
console.log('hello controller');
return { cats: 'get all cat api' };
}
@UseFilter를 사용해 사용할 수 있다.
만약 글로벌하게 filter를 사용하고 싶다면
import { HttpExceptionFilter } from 'src/common/exceptions/http-exception.filter';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(3000);
}
bootstrap();
main.ts로 가서app.useGlobalFilters(new HttpExceptionFilter()); 처럼 필터를 등록해주면 된다.
'node.js' 카테고리의 다른 글
Nest.js - 인터셉터 (0) | 2022.08.20 |
---|---|
Nest.js - pipes (0) | 2022.08.20 |
Nest.js - 미들웨어 (0) | 2022.08.20 |
Nest.js - 모듈 (0) | 2022.08.20 |
Nest.js - Providers (0) | 2022.08.20 |