@Controller('cats')
export class CatsController {
@Get()
getAllCat() { return 'get all cat api'}
}
-----------------------------------------------------
http://localhost:8000/cats/sdf
{
"statusCode" : 404,
"meessage" : "Catnot GET / 112",
"error" : "Not Found"
}
위와 같이 에러가 발생할 때 nestjs만에 규칙으로 자동으로 만들어준다. 실제로 서비스에 사용할 때 추가로 필요한 정보값도 같이 에러코드에 보내고 싶은 경우 nest에서 Http에 대한 에러는 HttpException으로 처리한다.
throw new HttpException() // nestJS에서 제공해주는 인터페이스를 사용
@Controller('cats')
export class CatsController {
@Get()
getAllCat() {
// (1) throw new HttpException('api is broken', 401)
throw new HttpException({ success: false, message: 'api is broken'}, 401) // 커스텀해서 오버라이딩을 해서 출력할 수 도 있다.
return 'get all cat api'
}
}
-----------------------------------------------------
http://localhost:8000/cats
// (1) {
// "statusCode" : 401,
// "meessage" : "api is broken",
// }
{
"success": false
"meessage" : "api is broken",
}
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) {
// ctx (context) : 실행 환경에 대한 컨택스트
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>(); // response 가져오기
const request = ctx.getRequest<Request>(); // request 가져오기
const status = exception.getStatus();
const error = exception.getResponse()
// res.status(400).send({"에러"}) express 와 같은형식
// (1) response
// .status(status) // 위에 보내준 status 받아서 보내주고
// .json({ // 위에 send가 json으로 한정으로 표현해준다.
// statusCode: status,
// timestamp: new Date().toISOString(),
// path: request.url,
// });
// 에러 메세지도 같이 보내주고 싶을 경우 : 'api broken', exception 안에 getResponse() 메서드가 있다. 에러메세지 인자가 이안으로 전달되서 에러메세지가 찍힌다.
response
.status(status) // 위에 보내준 status 받아서 보내주고
.json({ // 위에 send가 json으로 한정으로 표현해준다.
success : false,
timestamp: new Date().toISOString(),
path: request.url,
error, // error: error, 키와 벨류가 같은 경우 벨류 생략한다.
});
}
}
import { HttpExceptionFilter } from 'src/common/exceptions/http-exception.filter';
@Controller('cats')
export class CatsController {
@Get()
@UseFilters(HttpExceptionFilter)
getAllCat() {
throw new HttpException('api broken', 401)
return 'get all cat api'
}
}
-------------------------------------
http://localhost:8000/cats
- 필터링을 거쳤기 때문에 timestamp가 찍힌다.
// (1) {
// "statusCode": 401,
// "timestamp" : "2023-07-18-27T08:56:31.4472"
// "path" : "/cats",
// }
{
"seccess": false,
"timestamp" : "2023-07-18-27T08:56:31.4472"
"path" : "/cats",
"error" : "api broken"
}
@Controller('cats')
export class CatsController {
@Get()
@UseFilters(HttpExceptionFilter) <<
getAllCat() {
throw new HttpException('api broken', 401)
return 'get all cat api'
}
}
@Controller('cats')
@UseFilters(HttpExceptionFilter) <<
export class CatsController {
@Get()
getAllCat() {
throw new HttpException('api broken', 401)
return 'get all cat api'
}
}
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// 글로벌로 전역에 등록을 해주면된다. 앱에 대해서 필터링을 하나 추가해준것임.
app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(3000);
}
bootstrap();
http-exception.filter.ts
import {
Catch,
ExceptionFilter,
HttpException,
ArgumentsHost,
} 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
// message 같은 경우 string으로 찍힐 수도 있지만 배열로 찍힐 수도 있다.
| { error: string; statusCode: number; message: string | string[] };
// error 가 string 일 경우(인자값으로 넘겨주는 경우)와 아닐경우 분기처리하기
if (typeof error === 'string') {
response.status(status).json({
success: false,
timestamp: new Date().toISOString(),
path: request.url,
error,
});
} else {
// 404에러 처럼 nest 자체에서 발생하는 에러 비구조할당을 통해 보내주기
response.status(status).json({
success: false,
timestamp: new Date().toISOString(),
...error,
});
}
}
}
---------------------------------
{
"seccess": false,
"timestamp" : "2023-07-18-27T08:56:31.4472"
"statusConde" : 404,
"message" : "Cannot GET /112",
"error" : "Not Found"
}
너무 좋은 글이네요. 공유해주셔서 감사합니다.