Skip to content

Commit

Permalink
Feat/add interceptors and filter (#17)
Browse files Browse the repository at this point in the history
* Refactor: remove unused code

* Feat: Add exception filter

* Feat: Add response Interceptor

* Refactor: Add DB_HOST env

* Feat: Add logging interceptor

* Ci: Update pull_request rule

* Ci: Update yq cmd

* resolve conflict

* resolve conflict 222

---------

Co-authored-by: saehun <nycom13@gmail.com>
  • Loading branch information
chanwoonglee and saehun authored Jun 29, 2024
1 parent ad4bf5f commit 0d693e4
Showing 19 changed files with 340 additions and 15 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -5,9 +5,7 @@ on:
- main
- stage
pull_request:
branches:
- main
- stage
types: [opened, synchronize]

jobs:
test:
@@ -78,7 +76,7 @@ jobs:
- name: update yaml with yq
uses: mikefarah/yq@master
with:
cmd: yq '( select(di == 1) | .spec.template.spec.containers[0].image ) = "${{ secrets.NCP_CONTAINER_REGISTRY }}/${{ needs.ci.outputs.app_name }}:${{ needs.ci.outputs.version }}"' -i 'korrk/${{ needs.ci.outputs.app_name }}/${{ needs.ci.outputs.app_name }}.yaml'
cmd: yq '( select(di == 0) | .spec.template.spec.containers[0].image ) = "${{ secrets.NCP_CONTAINER_REGISTRY }}/${{ needs.ci.outputs.app_name }}:${{ needs.ci.outputs.version }}"' -i 'korrk/${{ needs.ci.outputs.app_name }}/${{ needs.ci.outputs.app_name }}.yaml'

- name: Update tag
run: |
1 change: 1 addition & 0 deletions additional.d.ts
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ declare namespace NodeJS {
NODE_ENV: string;
JWT_PRIVATE_KEY: string;
JWT_PUBLIC_KEY: string;
DB_HOST: string;
DB_USER: string;
DB_NAME: string;
DB_PASSWORD: string;
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -34,6 +34,7 @@
"@mikro-orm/migrations": "^6.2.9",
"@mikro-orm/nestjs": "^6.0.2",
"@mikro-orm/postgresql": "^6.2.9",
"@mikro-orm/reflection": "^6.2.9",
"@mikro-orm/sql-highlighter": "^1.0.1",
"@nestjs/axios": "^3.0.2",
"@nestjs/common": "^10.3.9",
@@ -47,6 +48,8 @@
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"joi": "^17.13.3",
"moment-timezone": "^0.5.45",
"passport-custom": "^1.1.1",
"passport-jwt": "^4.0.1",
"passport-kakao": "^1.0.1",
"reflect-metadata": "^0.2.2",
103 changes: 103 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Module } from '@nestjs/common';
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

import { MikroOrmModule } from '@mikro-orm/nestjs';

import { LoggerMiddleware } from 'src/core/intercepters/logging.interceptor';

import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module';
@@ -30,4 +32,8 @@ import { UserModule } from './user/user.module';
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer): void {
consumer.apply(LoggerMiddleware).forRoutes('/*');
}
}
3 changes: 3 additions & 0 deletions src/common/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const IS_DEV = process.env.NODE_ENV === 'development';
export const IS_STAGE = process.env.NODE_ENV === 'stage';
export const IS_PROD = process.env.NODE_ENV === 'production';
85 changes: 85 additions & 0 deletions src/core/exception-filters/custom-exception.filter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import {
ArgumentsHost,
Catch,
ExceptionFilter,
HttpException,
Logger,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

import { Response } from 'express';

import { IS_DEV } from 'src/common/constants';

type ResponseBody = {
statusCode: number;
message: string;
error?: string;
};

@Catch()
export class CustomExceptionFilter implements ExceptionFilter {
private readonly logger = new Logger();
constructor(private readonly configService: ConfigService) {}

async catch(exception: Error, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const request = ctx.getRequest<Request>();
const response = ctx.getResponse<Response>();

const responseBody: ResponseBody = {
statusCode: 500,
message: '예상치 못한 에러가 발생했습니다. 노드팀을 채찍질 해주세요',
};

if (exception instanceof HttpException) {
const httpExceptionResponse = exception.getResponse() as
| string
| ResponseBody;
responseBody.statusCode = exception.getStatus();
responseBody.message =
typeof httpExceptionResponse === 'string'
? httpExceptionResponse
: httpExceptionResponse.message;
}

if (exception instanceof Error && responseBody.statusCode === 500) {
this.logger.error(
`api : ${request.method} ${request.url} message : ${exception.message}`,
);
if (!IS_DEV) {
await this.handle(request, exception);
}
}

response.status(responseBody.statusCode).json(responseBody);
}

private async handle(request: Request, error: Error) {
//TODO: DISCORD_WEBHOOK_URL 추가 예정
const discordWebhook = this.configService.get('DISCORD_WEBHOOK_URL');
const content = this.parseError(request, error);

await fetch(discordWebhook, {
method: 'post',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content }),
});
}

private parseError(request: Request, error: Error): string {
return `노드팀 채찍 맞아라~~ 🦹🏿‍♀️👹🦹🏿
에러 발생 API : ${request.method} ${request.url}
에러 메세지 : ${error.message}
에러 위치 : ${error.stack
.split('\n')
.slice(0, 2)
.map((message) => message.trim())
.join('\n')}
당장 고쳐서 올렷!
`;
}
}
Loading

0 comments on commit 0d693e4

Please sign in to comment.