verifyComment
함수 활용오늘 코멘트 서비스에서 verifyComment
함수를 정의하여 updateComment
와 deleteComment
에서 간편하게 사용할 수 있도록 만들었다.
private async verifyComment(id: number, userId: number) {
const comment = await this.commentRepository.findOneBy({ id });
if (_.isNil(comment) || comment.userId !== userId) {
throw new CommentPermissionException();
}
}
위 함수를 사용하여 아래와 같이 간결한 코드 작성이 가능해졌다.
await this.verifyComment(id, userId);
이번 프로젝트에서 처음으로 Lodash를 사용해보았다. Lodash는 JavaScript에서 강력한 유틸리티 라이브러리로, 코드의 가독성을 높이고 예외 처리를 간편하게 할 수 있도록 도와준다.
import _ from "lodash";
하지만 Lodash 전체를 가져오는 방식은 권장되지 않는다. 따라서 필요한 기능만 개별적으로 가져오는 것이 좋다.
import { isNil } from "lodash";
isNil(value)
: 값이 null
또는 undefined
인지 확인isEmpty(value)
: 값이 비어 있는지 확인 (null
, undefined
, 빈 배열, 빈 객체 등)get(object, path, defaultValue)
: 안전하게 객체 속성 접근set(object, path, value)
: 객체 속성 안전하게 설정omit(object, keys)
: 특정 속성을 제외한 객체 반환pick(object, keys)
: 특정 속성만 포함한 객체 반환uniq(array)
: 배열 중복 제거flattenDeep(array)
: 중첩 배열을 완전히 평탄화difference(array, values)
: 배열에서 특정 값 제거debounce(func, wait)
: 마지막 입력 후 일정 시간 뒤 실행 (검색창 최적화)throttle(func, wait)
: 일정 시간마다 한 번만 실행 (스크롤 이벤트 최적화)capitalize(string)
: 첫 글자 대문자로 변환camelCase(string)
: helloWorld
형태로 변환전역 예외 처리를 src/common/exception/http-exception.filter.ts
파일에서 정의하였다.
import {
ExceptionFilter, Catch, ArgumentsHost, HttpException,
UnauthorizedException, BadRequestException, NotFoundException,
ConflictException, InternalServerErrorException, ForbiddenException,
} 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 status = exception.getStatus();
const message = exception.message || '서버 에러가 발생했습니다.';
let errorType = 'HttpException';
if (exception instanceof UnauthorizedException) errorType = 'UnauthorizedException';
else if (exception instanceof BadRequestException) errorType = 'BadRequestException';
else if (exception instanceof NotFoundException) errorType = 'NotFoundException';
else if (exception instanceof ConflictException) errorType = 'ConflictException';
else if (exception instanceof InternalServerErrorException) errorType = 'InternalServerErrorException';
else if (exception instanceof ForbiddenException) errorType = 'ForbiddenException';
response.status(status).json({
statusCode: status,
errorType: errorType,
message: message,
});
}
}
main.ts
에 해당 예외 필터를 등록하여 글로벌 예외 처리를 적용할 수 있다.
import { HttpExceptionFilter } from './common/exceptions/http-exception.filter';
app.useGlobalFilters(new HttpExceptionFilter());
예외 처리를 src/common/exception/comment.exception.ts
파일에 정리하여 사용했다.
import { NotFoundException, BadRequestException } from '@nestjs/common';
export class CommentNotFoundException extends NotFoundException {
constructor() {
super('댓글을 찾을 수 없습니다.');
}
}
export class CommentPermissionException extends NotFoundException {
constructor() {
super('댓글을 찾을 수 없거나 수정/삭제할 권한이 없습니다.');
}
}
export class EmptyCommentException extends BadRequestException {
constructor() {
super('댓글 내용을 비울 수 없습니다.');
}
}
export class CommentLengthExceededException extends BadRequestException {
constructor() {
super('댓글 내용은 50자를 넘길 수 없습니다.');
}
}
if (_.isEmpty(content.trim())) {
throw new EmptyCommentException();
}
if (content.length > 50) {
throw new CommentLengthExceededException();
}
if (_.isNil(comment)) {
throw new CommentNotFoundException();
}
if (_.isNil(comment) || comment.userId !== userId) {
throw new CommentPermissionException();
}
verifyComment
함수를 정의하여 코드의 재사용성을 높일 수 있었다.