Exception
Nest๋ application ๋ด์์ ๋ฐ์ํ๋ ์๋ฌ๋ฅผ ํธ๋ค๋งํ๊ธฐ ์ํด exception filter
๋ฅผ ๊ฐ์ง๊ณ ์๋ฌ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค. default exception filter๋ BaseExceptionFilter
์ด๊ณ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ก ์ด๋ฃจ์ด์ ธ ์์ต๋๋ค.
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
29
30
31
| // nest/packages/core/exceptions/base-exception-filter.ts
export class BaseExceptionFilter<T = any> implements ExceptionFilter<T> {
// ...
catch(exception: T, host: ArgumentsHost) {
// ...
if (!(exception instanceof HttpException)) {
return this.handleUnknownError(exception, host, applicationRef);
}
const res = exception.getResponse();
const message = isObject(res)
? res
: {
statusCode: exception.getStatus(),
message: res,
};
// ...
}
public handleUnknownError(
exception: T,
host: ArgumentsHost,
applicationRef: AbstractHttpAdapter | HttpServer,
) {
const body = {
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
message: MESSAGES.UNKNOWN_EXCEPTION_MESSAGE,
};
// ...
}
}
|
nest๋ ์ฐ๋ฆฌ๊ฐ ์ดํ๋ฆฌ์ผ์ด์
๋ด์์ HttpException
์ผ๋ก ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ๋ฅผ ๊ธฐ๋ํฉ๋๋ค. ๊ทธ๋ ์ง ์๋ค๋ฉด, nest ๋ Internal server error๋ฅผ ๋ด์ฃผ๊ฒ ๋ฉ๋๋ค.
HttpException
์ 3๊ฐ์ ์ธ์๋ฅผ ๊ฐ๊ณ ์์ต๋๋ค.
statusCode
message
: string / Record(json)options
message
์ ๊ฐ์ฒด๋ฅผ ๋๊ฒจ์ฃผ์ด ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ๋ค๋ฉด, ์ด๋ฅผ serialize ํ์ฌ ์ด๋ ํ format์ผ๋ก ๋ณ๊ฒฝ ํ response๋ก ๋๊ฒจ์ฃผ๊ฒ ๋ฉ๋๋ค.
options ๊ฐ์ฒด์ {cause:error}
์ ๊ฐ์ด ๋๊ฒจ ์ค๋ค๋ฉด, ๋ก๊น
๋ชฉ์ ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
Exception Filter Customizing
์๋ฌ๋ฅผ ์ฒ๋ฆฌํ ๋๋ BaseExceptionFilter ๋ฅผ default filter๋ก ์ฌ์ฉํฉ๋๋ค. ์ด๋ฅผ ๋ณ๊ฒฝํ๊ณ ์ถ๋ค๋ฉด, catch()
๋ฉ์๋ ๋ด๋ถ์ ์ํ๋ ๋์์ ์ฒ๋ฆฌํ๋ฉด ๋ฉ๋๋ค.
1
2
3
4
5
6
7
8
9
10
| import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
@Catch()
export class ExceptionsLoggerFilter extends BaseExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
console.log('Exception thrown', exception);
super.catch(exception, host);
}
}
|
์ฌ๊ธฐ์ @Catch()
๋ฐ์ฝ๋ ์ดํฐ ๋ด๋ถ์ ํน์ ํ exception๋ง ์ฒ๋ฆฌํ๋๋ก ํ ์ ์์ต๋๋ค.
BaseExceptionFilter๋ฅผ ์์๋ฐ๊ฒ ๋๋ฉด catch()
๋ฉ์๋๋ฅผ ์ํํ๋๋ฐ, ์ด ๋ฉ์๋์๋ 2๊ฐ์ ์ธ์๊ฐ ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค.
HttpException
: ํ์ฌ ์ฒ๋ฆฌ ๋๋ ์์ธ ๊ฐ์ฒด๋ฅผ ์๋ฏธํฉ๋๋ค.AugumentsHost
: Excecution context
์ ๊ด๋ จ์๋ ๊ฐ์ฒด์ธ๋ฐ, ์ด์ ๋ํ ์ค๋ช
์ ๊ธธ์ด์ง ๊ฒ ๊ฐ์ผ๋ฏ๋ก ๋ค์ ํฌ์คํ
์ผ๋ก ๋ฏธ๋ฃจ๋๋ก ํ๊ฒ ์ต๋๋ค.
์ด๋ ๊ฒ filter๋ฅผ customizing ํ๊ณ ๋์๋, 3๊ฐ์ง ๋ฐฉ๋ฒ์ ํตํด ์ดํ๋ฆฌ์ผ์ด์
์ ์ ์ฉํ ์ ์์ต๋๋ค.
- main.ts์ app.useGlobalFilters ๋ฏธ๋ค์จ์ด๋ฅผ ๋ฑ๋ก
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import { HttpAdapterHost, NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as cookieParser from 'cookie-parser';
import { ExceptionsLoggerFilter } from './utils/exceptionsLogger.filter';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const { httpAdapter } = app.get(HttpAdapterHost);
app.useGlobalFilters(new ExceptionsLoggerFilter(httpAdapter));
app.use(cookieParser());
await app.listen(3000);
}
bootstrap();
|
2. AppModule ์ inject
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| import { Module } from '@nestjs/common';
import { ExceptionsLoggerFilter } from './utils/exceptionsLogger.filter';
import { APP_FILTER } from '@nestjs/core';
@Module({
// ...
providers: [
{
provide: APP_FILTER,
useClass: ExceptionsLoggerFilter,
},
],
})
export class AppModule {}
|
3. `@UseFilters` ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฌ์ฉ
1
2
3
4
5
| @Get(':id')
@UseFilters(ExceptionsLoggerFilter)
getPostById(@Param('id') id: string) {
return this.postsService.getPostById(Number(id));
}
|
Validation