나의 첫 번째 [BugFixHub] 팀 프로젝트를 진행했다.
BugFixHub는 "Stack Overflow"를 모티브 하여 개발 정보를 공유하고 질문과 답변을 할 수 있는 저장소이다.
▶ [GitHub 링크]
우리는 각 파트들을 나누어 개발을 진행 했고, 그중 나는 Friend, Comment Like 파트를 맡게 되었다.
개발을 진행하면서 Comment Like 부분에서 문제가 발생되어 관련 내용을 Trouble Shooting을 진행하려고 한다.
▶ Postman API 호출 리스트
요청 URL | 구분 | 요청사항 | API 호출 결과 | 상태 코드 |
/posts/postId/comments/commentId/like | 댓글 좋아요 |
좋아요 완료 | 댓글 좋아요ID, UserId, CommentId 반환 | 201, CREATED |
이미 전송된 요청 | 이미 좋아요를 남긴 댓글입니다. | 400, BAD REQUEST | ||
댓글이 존재하지 않은 경우 | 댓글을 찾을 수 없습니다. | 404, NOT FOUND | ||
댓글과 게시글의 관계 오류 | 댓글ID와 게시글ID의 관계가 유효하지 않습니다. | 400, BAD REQUEST | ||
댓글 좋아요 취소 |
좋아요 취소 | - |
204 NO CONTENT | |
좋아요를 안한 경우 | 좋아요를 남기지 않은 댓글입니다. | 400, BAD REQUEST |
1. 배경
1) 문제 상황:
① Comment Like(댓글 좋아요) 코드 구현 후 Postman으로 API 호출 결과를 확인하던 중,
게시글이 존재하지 않음에도 불구하고, 댓글에 좋아요를 누를 때 "이미 좋아요를 남긴 댓글입니다"라는 잘못된 오류 메시지가 반환됨.
② 이를 해결하기 위해 댓글과 게시글의 관계를 검증하는 "validateCommentAndPostRelation" 메서드를 추가했으나,
추가적인 문제 발생.
-> 댓글이 존재하지 않는 경우에도 "게시글 ID와 댓글 ID의 관계가 유효하지 않습니다. " 오류 메시지가 우선적으로 표시됨.
▶ 수정 전 로직
// 게시글과 댓글 관계 검증 로직 추가
private void validateCommentAndPostRelation(Long commentId, Long postId) {
if (!commentRepository.existsByIdAndPostId(commentId, postId)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "게시글 ID와 댓글 ID의 관계가 유효하지 않습니다.");
}
}
// 댓글 좋아요
@Override
@Transactional
public CommentLikeResDto likeComment(Long commentId, Long postId, Long userId) {
// 게시글과 댓글 관계 검증
validateCommentAndPostRelation(commentId, postId);
Comment comment = commentRepository.findByIdAndDeletedFalse(commentId)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "댓글을 찾을 수 없습니다."));
if (comment.getUser().getId().equals(userId)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "본인 댓글에는 좋아요를 남길 수 없습니다");
}
if (commentLikeRepository.existsByCommentIdAndUserId(commentId, userId)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "이미 좋아요를 남긴 댓글입니다.");
}
User user = userRepository.findById(userId)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "사용자를 찾을 수 없습니다."));
CommentLike commentLike = new CommentLike(user, comment);
commentLikeRepository.save(commentLike);
return new CommentLikeResDto(commentLike);
}
2) 원인 분석
위 댓글 좋아요 로직에서 댓글 여부를 확인하기도 전에 게시글과 댓글 관계를 검증하는 "validateCommentAndPostRelation" 메서드가 먼저 실행되면서, 댓글이 삭제되거나 존재하지 않아도 메서드의 흐름을 종료하고 예외를 호출자에게 반환됨.
※ throw new 방식의 예외 처리
- 호출되는 즉시 현재 실행 중인 메서드의 흐름을 종료하고 예외를 호출자에게 보여준다.
- 예외를 발생시키는 메서드가 실행 순서보다 앞에 있다면, 이후의 중요한 검증 로직은 실행되지 않는다.
- Postman 호출 예시:
/posts/11/comments/commentId/like
2. 절정
위와 같은 문제를 해결하기 위해 게시글에 댓글 존재 여부를 확인 후, 게시글과 댓글간의 관계를 검증할 수 있도록 순서를 조정했다.
3. 결과
- 댓글 존재를 먼저 확인하여, 댓글과 게시글 관계검증은 댓글이 유효한 경우에만 실행될 수 있도록 순서 변경
▶ 수정 후 로직
// 게시글과 댓글 관계 검증(추가)
private void validateCommentAndPostRelation(Long commentId, Long postId) {
if (!commentRepository.existsByIdAndPostId(commentId, postId)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "게시글 ID와 댓글 ID의 관계가 유효하지 않습니다.");
}
}
// 댓글 좋아요
@Override
@Transactional
public CommentLikeResDto likeComment(Long commentId, Long postId, Long userId) {
1. 댓글 존재 여부 확인
Comment comment = commentRepository.findByIdAndDeletedFalse(commentId)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "댓글을 찾을 수 없습니다."));
2. 게시글과 댓글 관계 검증
validateCommentAndPostRelation(commentId, postId);
if (comment.getUser().getId().equals(userId)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "본인 댓글에는 좋아요를 남길 수 없습니다");
}
if (commentLikeRepository.existsByCommentIdAndUserId(commentId, userId)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "이미 좋아요를 남긴 댓글입니다.");
}
.
.
.
.
.
위와 같이 코드 수정 후 IntelliJ 재 실행했고 Postman을 호출했다.
검증 순서를 조정한 후 정상적으로 호출되는 것을 확인했다.
1. 댓글을 찾을 수 없는 경우
2. 생성되지 않은 게시글에 댓글 좋아요를 누르는 경우
'오늘의 배움(TIL) > 트러블슈팅' 카테고리의 다른 글
[250118] Jackson 역직렬화 에러 발생 (0) | 2025.01.18 |
---|---|
[241223] AWS S3 권한 문제 및 데이터 무결성, 중복 데이터 이슈 (0) | 2024.12.23 |
[Trouble Shooting] ItemTest 테스트코드 관련 트러블 슈팅 (1) | 2024.12.18 |
[Trouble Shooting] Jackson의 직렬화 관련 트러블 슈팅 (0) | 2024.11.28 |
Spring 숙련 주차 과제: 일정 관리 앱 Develop 트러블슈팅 (2) | 2024.11.15 |