From bb931903f89cdc02c5bb8e19ec83d2bf87777266 Mon Sep 17 00:00:00 2001 From: Minjae Chung Date: Sat, 21 Feb 2026 22:11:26 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[refactor]=20BusinessException=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EC=97=B4=20=EC=82=AC=EC=9A=A9=20=EC=A0=9C=EA=B1=B0=20?= =?UTF-8?q?=EB=B0=8F=20=EC=97=90=EB=9F=AC=20=EB=A1=9C=EA=B9=85=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .../server/auth/application/AuthService.java | 6 ++-- .../MailVerificationServiceImpl.java | 5 +-- .../auth/exception/AuthErrorStatus.java | 5 +++ .../comment/application/CommentService.java | 13 ++++---- .../comment/exception/CommentErrorStatus.java | 22 +++++++++++++ .../common/exception/CommonErrorStatus.java | 1 + .../common/exception/ErrorCategory.java | 4 ++- .../exception/GlobalExceptionHandler.java | 2 +- .../server/common/util/PagingUtils.java | 3 +- .../notice/utils/NoticeUserValidator.java | 3 +- .../application/NotificationService.java | 3 +- .../exception/NotificationErrorStatus.java | 20 +++++++++++ .../server/post/application/PostService.java | 5 +-- .../post/exception/PostErrorStatus.java | 20 +++++++++++ .../server/post/utils/PostUserValidator.java | 3 +- .../server/user/application/UserService.java | 33 +++++++++---------- .../user/exception/UserErrorStatus.java | 25 ++++++++++++++ 18 files changed, 138 insertions(+), 36 deletions(-) create mode 100644 src/main/java/com/daramg/server/comment/exception/CommentErrorStatus.java create mode 100644 src/main/java/com/daramg/server/notification/exception/NotificationErrorStatus.java create mode 100644 src/main/java/com/daramg/server/post/exception/PostErrorStatus.java create mode 100644 src/main/java/com/daramg/server/user/exception/UserErrorStatus.java diff --git a/.gitignore b/.gitignore index f09037b..5ed01b9 100644 --- a/.gitignore +++ b/.gitignore @@ -39,5 +39,6 @@ out/ ### 보안정보 application-secret.yml +*.pem src/main/generated \ No newline at end of file diff --git a/src/main/java/com/daramg/server/auth/application/AuthService.java b/src/main/java/com/daramg/server/auth/application/AuthService.java index fef1213..6b2c8cc 100644 --- a/src/main/java/com/daramg/server/auth/application/AuthService.java +++ b/src/main/java/com/daramg/server/auth/application/AuthService.java @@ -40,7 +40,7 @@ public class AuthService { public void signup(SignupRequestDto dto, MultipartFile image){ if (userRepository.existsByEmail(dto.getEmail())) { - throw new BusinessException("중복된 이메일입니다."); + throw new BusinessException(AuthErrorStatus.DUPLICATE_EMAIL); } userRepository.findByEmailAndUserStatus(dto.getEmail(), UserStatus.DELETED) .ifPresent(deletedUser -> { @@ -50,7 +50,7 @@ public void signup(SignupRequestDto dto, MultipartFile image){ } }); if (userRepository.existsByNickname(dto.getNickname())){ - throw new BusinessException("중복된 닉네임입니다."); + throw new BusinessException(AuthErrorStatus.DUPLICATE_NICKNAME); } // TODO: bio, 닉네임에 금칙어 검사 String encodedPassword = passwordEncoder.encode(dto.getPassword()); @@ -117,7 +117,7 @@ public void logout(User user){ public void signOut(User user, com.daramg.server.user.dto.PasswordRequestDto request){ if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) { - throw new BusinessException("비밀번호가 일치하지 않습니다."); + throw new BusinessException(AuthErrorStatus.INVALID_PASSWORD); } redisTemplate.delete(user.getEmail()); user.withdraw(); diff --git a/src/main/java/com/daramg/server/auth/application/MailVerificationServiceImpl.java b/src/main/java/com/daramg/server/auth/application/MailVerificationServiceImpl.java index 86c79ad..340a66a 100644 --- a/src/main/java/com/daramg/server/auth/application/MailVerificationServiceImpl.java +++ b/src/main/java/com/daramg/server/auth/application/MailVerificationServiceImpl.java @@ -9,6 +9,7 @@ import com.daramg.server.auth.util.MimeMessageGenerator; import com.daramg.server.auth.util.VerificationCodeGenerator; import com.daramg.server.common.exception.BusinessException; +import com.daramg.server.user.exception.UserErrorStatus; import com.daramg.server.user.repository.UserRepository; import jakarta.mail.MessagingException; import jakarta.mail.internet.MimeMessage; @@ -35,7 +36,7 @@ public void sendVerificationEmail(EmailVerificationRequestDto request) { case SIGNUP -> sendForSignup(request); case PASSWORD_RESET -> sendForPasswordReset(request); case EMAIL_CHANGE -> sendForEmailChange(request); - default -> throw new BusinessException("지원하지 않는 이메일 발송 목적입니다."); + default -> throw new BusinessException(AuthErrorStatus.UNSUPPORTED_EMAIL_PURPOSE); } } @@ -53,7 +54,7 @@ private void sendForPasswordReset(EmailVerificationRequestDto request) { private void sendForEmailChange(EmailVerificationRequestDto request) { if (userRepository.existsByEmail(request.getEmail()) && !request.getEmail().equals(request.getOriginalEmail())) { - throw new BusinessException("이미 가입되어 있는 이메일입니다."); + throw new BusinessException(UserErrorStatus.DUPLICATE_EMAIL); } sendVerificationCode(request); } diff --git a/src/main/java/com/daramg/server/auth/exception/AuthErrorStatus.java b/src/main/java/com/daramg/server/auth/exception/AuthErrorStatus.java index 4d17d7f..a6bd042 100644 --- a/src/main/java/com/daramg/server/auth/exception/AuthErrorStatus.java +++ b/src/main/java/com/daramg/server/auth/exception/AuthErrorStatus.java @@ -26,6 +26,11 @@ public enum AuthErrorStatus implements BaseErrorCode { USER_NOT_FOUND_EXCEPTION(HttpStatus.NOT_FOUND, ErrorCategory.AUTH.generate(404_1), "존재하지 않는 사용자입니다."), + DUPLICATE_EMAIL(HttpStatus.CONFLICT, ErrorCategory.AUTH.generate(409_1), "중복된 이메일입니다."), + DUPLICATE_NICKNAME(HttpStatus.CONFLICT, ErrorCategory.AUTH.generate(409_2), "중복된 닉네임입니다."), + INVALID_PASSWORD(HttpStatus.BAD_REQUEST, ErrorCategory.AUTH.generate(400_8), "비밀번호가 일치하지 않습니다."), + UNSUPPORTED_EMAIL_PURPOSE(HttpStatus.BAD_REQUEST, ErrorCategory.AUTH.generate(400_9), "지원하지 않는 이메일 발송 목적입니다."), + SEND_VERIFICATION_EMAIL_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, ErrorCategory.AUTH.generate(500), "이메일 전송에 실패했습니다."), REDIS_CONNECTION_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, ErrorCategory.AUTH.generate(500_1), "Redis 연결에 실패했습니다. 서버 관리자에게 문의 바랍니다."); diff --git a/src/main/java/com/daramg/server/comment/application/CommentService.java b/src/main/java/com/daramg/server/comment/application/CommentService.java index e9b8053..53a7508 100644 --- a/src/main/java/com/daramg/server/comment/application/CommentService.java +++ b/src/main/java/com/daramg/server/comment/application/CommentService.java @@ -6,6 +6,7 @@ import com.daramg.server.comment.repository.CommentLikeRepository; import com.daramg.server.comment.repository.CommentRepository; import com.daramg.server.common.application.EntityUtils; +import com.daramg.server.comment.exception.CommentErrorStatus; import com.daramg.server.common.exception.BusinessException; import com.daramg.server.post.domain.Post; import com.daramg.server.notification.domain.NotificationType; @@ -31,7 +32,7 @@ public class CommentService { public void createComment(Long postId, CommentCreateDto request, User user){ Post post = entityUtils.getEntity(postId, Post.class); if (post.isBlocked()){ - throw new BusinessException("블락된 포스트에는 댓글을 남길 수 없습니다."); + throw new BusinessException(CommentErrorStatus.BLOCKED_POST); } Comment comment = Comment.of( @@ -53,11 +54,11 @@ public void createComment(Long postId, CommentCreateDto request, User user){ public void createReply(Long commentId, CommentReplyCreateDto request, User user){ Comment parentComment = entityUtils.getEntity(commentId, Comment.class); if (parentComment.isDeleted() || parentComment.isBlocked()){ - throw new BusinessException("삭제되었거나 블락된 댓글에는 대댓글을 남길 수 없습니다."); + throw new BusinessException(CommentErrorStatus.BLOCKED_OR_DELETED_COMMENT); } Post post = parentComment.getPost(); if (post.isBlocked()){ - throw new BusinessException("블락된 포스트에는 댓글을 남길 수 없습니다."); + throw new BusinessException(CommentErrorStatus.BLOCKED_POST); } Comment reply = Comment.of( @@ -79,7 +80,7 @@ public void createReply(Long commentId, CommentReplyCreateDto request, User user public CommentLikeResponseDto toggleCommentLike(Long commentId, User user){ Comment comment = entityUtils.getEntity(commentId, Comment.class); if (comment.isDeleted() || comment.isBlocked()){ - throw new BusinessException("삭제되었거나 블락된 댓글에는 좋아요를 누를 수 없습니다."); + throw new BusinessException(CommentErrorStatus.BLOCKED_OR_DELETED_COMMENT); } boolean alreadyLiked = commentLikeRepository @@ -105,10 +106,10 @@ public void deleteComment(Long commentId, User user){ Comment comment = entityUtils.getEntity(commentId, Comment.class); if (comment.isDeleted()){ - throw new BusinessException("이미 삭제 처리된 댓글입니다."); + throw new BusinessException(CommentErrorStatus.ALREADY_DELETED); } if (comment.getUser() == null || !comment.getUser().getId().equals(user.getId())){ - throw new BusinessException("댓글을 작성한 유저만 댓글을 삭제할 수 있습니다."); + throw new BusinessException(CommentErrorStatus.NOT_COMMENT_AUTHOR); } comment.softDelete(); diff --git a/src/main/java/com/daramg/server/comment/exception/CommentErrorStatus.java b/src/main/java/com/daramg/server/comment/exception/CommentErrorStatus.java new file mode 100644 index 0000000..dcd8b4c --- /dev/null +++ b/src/main/java/com/daramg/server/comment/exception/CommentErrorStatus.java @@ -0,0 +1,22 @@ +package com.daramg.server.comment.exception; + +import com.daramg.server.common.exception.BaseErrorCode; +import com.daramg.server.common.exception.ErrorCategory; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public enum CommentErrorStatus implements BaseErrorCode { + + BLOCKED_POST(HttpStatus.FORBIDDEN, ErrorCategory.COMMENT.generate(403_1), "블락된 포스트에는 댓글을 남길 수 없습니다."), + BLOCKED_OR_DELETED_COMMENT(HttpStatus.FORBIDDEN, ErrorCategory.COMMENT.generate(403_2), "삭제되었거나 블락된 댓글입니다."), + ALREADY_DELETED(HttpStatus.BAD_REQUEST, ErrorCategory.COMMENT.generate(400_1), "이미 삭제 처리된 댓글입니다."), + NOT_COMMENT_AUTHOR(HttpStatus.FORBIDDEN, ErrorCategory.COMMENT.generate(403_3), "댓글 작성자만 삭제할 수 있습니다."); + + private final HttpStatus httpStatus; + private final String code; + private final String message; +} diff --git a/src/main/java/com/daramg/server/common/exception/CommonErrorStatus.java b/src/main/java/com/daramg/server/common/exception/CommonErrorStatus.java index 56adb0b..1321aaf 100644 --- a/src/main/java/com/daramg/server/common/exception/CommonErrorStatus.java +++ b/src/main/java/com/daramg/server/common/exception/CommonErrorStatus.java @@ -13,6 +13,7 @@ public enum CommonErrorStatus implements BaseErrorCode { GATEWAY_TIMEOUT(HttpStatus.GATEWAY_TIMEOUT, ErrorCategory.COMMON.generate(504), "타임아웃 에러, 서버 관리자에게 문의 바랍니다."), BAD_REQUEST(HttpStatus.BAD_REQUEST, ErrorCategory.COMMON.generate(400), "유효하지 않은 요청입니다."), + INVALID_CURSOR(HttpStatus.BAD_REQUEST, ErrorCategory.COMMON.generate(400_1), "유효하지 않은 커서 포맷입니다."), UNAUTHORIZED(HttpStatus.UNAUTHORIZED, ErrorCategory.COMMON.generate(401), "인증이 필요합니다."), FORBIDDEN(HttpStatus.FORBIDDEN, ErrorCategory.COMMON.generate(403), "금지된 요청입니다."), NOT_FOUND(HttpStatus.NOT_FOUND , ErrorCategory.COMMON.generate(404), "찾을 수 없는 리소스입니다."); diff --git a/src/main/java/com/daramg/server/common/exception/ErrorCategory.java b/src/main/java/com/daramg/server/common/exception/ErrorCategory.java index 9614d5b..2459f21 100644 --- a/src/main/java/com/daramg/server/common/exception/ErrorCategory.java +++ b/src/main/java/com/daramg/server/common/exception/ErrorCategory.java @@ -6,7 +6,9 @@ public enum ErrorCategory { AUTH("AUTH_"), USER("USER_"), POST("POST_"), - IMAGE("IMAGE_"); + IMAGE("IMAGE_"), + COMMENT("COMMENT_"), + NOTIFICATION("NOTIFICATION_"); private final String prefix; diff --git a/src/main/java/com/daramg/server/common/exception/GlobalExceptionHandler.java b/src/main/java/com/daramg/server/common/exception/GlobalExceptionHandler.java index f6c7bad..fda1f10 100644 --- a/src/main/java/com/daramg/server/common/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/daramg/server/common/exception/GlobalExceptionHandler.java @@ -29,7 +29,7 @@ public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { public ResponseEntity handleGeneralException(BusinessException e) { BaseErrorCode errorCode = e.getErrorCode(); - log.warn("GeneralException: {}", errorCode.getMessage()); + log.warn("GeneralException: {} - {}", errorCode.getMessage(), e.getMessage()); return ResponseEntity .status(errorCode.getHttpStatus()) .body(ErrorResponse.of(errorCode)); diff --git a/src/main/java/com/daramg/server/common/util/PagingUtils.java b/src/main/java/com/daramg/server/common/util/PagingUtils.java index c5a1000..1f9f941 100644 --- a/src/main/java/com/daramg/server/common/util/PagingUtils.java +++ b/src/main/java/com/daramg/server/common/util/PagingUtils.java @@ -3,6 +3,7 @@ import com.daramg.server.common.dto.PageRequestDto; import com.daramg.server.common.dto.PageResponseDto; import com.daramg.server.common.exception.BusinessException; +import com.daramg.server.common.exception.CommonErrorStatus; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.DateTimePath; import com.querydsl.core.types.dsl.NumberPath; @@ -116,7 +117,7 @@ private Cursor decodeCursor(String cursorString) { return new Cursor(LocalDateTime.parse(parts[0]), Long.parseLong(parts[1])); } catch (IllegalArgumentException | ArrayIndexOutOfBoundsException | DateTimeParseException e) { - throw new BusinessException("유효하지 않은 커서 포맷입니다."); + throw new BusinessException(CommonErrorStatus.INVALID_CURSOR); } } diff --git a/src/main/java/com/daramg/server/notice/utils/NoticeUserValidator.java b/src/main/java/com/daramg/server/notice/utils/NoticeUserValidator.java index 55ae35d..8d0eb2f 100644 --- a/src/main/java/com/daramg/server/notice/utils/NoticeUserValidator.java +++ b/src/main/java/com/daramg/server/notice/utils/NoticeUserValidator.java @@ -2,13 +2,14 @@ import com.daramg.server.common.exception.BusinessException; import com.daramg.server.notice.domain.Notice; +import com.daramg.server.notification.exception.NotificationErrorStatus; import com.daramg.server.user.domain.User; public class NoticeUserValidator { public static void check(Notice notice, User user) { if (!notice.getUser().getId().equals(user.getId())) { - throw new BusinessException("공지사항의 작성자가 일치하지 않습니다."); + throw new BusinessException(NotificationErrorStatus.NOT_NOTICE_AUTHOR); } } } diff --git a/src/main/java/com/daramg/server/notification/application/NotificationService.java b/src/main/java/com/daramg/server/notification/application/NotificationService.java index e55dd7a..7860d9f 100644 --- a/src/main/java/com/daramg/server/notification/application/NotificationService.java +++ b/src/main/java/com/daramg/server/notification/application/NotificationService.java @@ -2,6 +2,7 @@ import com.daramg.server.common.application.EntityUtils; import com.daramg.server.common.exception.BusinessException; +import com.daramg.server.notification.exception.NotificationErrorStatus; import com.daramg.server.notification.domain.Notification; import com.daramg.server.notification.repository.NotificationRepository; import com.daramg.server.user.domain.User; @@ -35,7 +36,7 @@ public void delete(Long notificationId, User user) { private void validateReceiver(Notification notification, User user) { if (!notification.getReceiver().getId().equals(user.getId())) { - throw new BusinessException("본인의 알림만 처리할 수 있습니다."); + throw new BusinessException(NotificationErrorStatus.NOT_OWN_NOTIFICATION); } } } diff --git a/src/main/java/com/daramg/server/notification/exception/NotificationErrorStatus.java b/src/main/java/com/daramg/server/notification/exception/NotificationErrorStatus.java new file mode 100644 index 0000000..b83b57a --- /dev/null +++ b/src/main/java/com/daramg/server/notification/exception/NotificationErrorStatus.java @@ -0,0 +1,20 @@ +package com.daramg.server.notification.exception; + +import com.daramg.server.common.exception.BaseErrorCode; +import com.daramg.server.common.exception.ErrorCategory; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public enum NotificationErrorStatus implements BaseErrorCode { + + NOT_OWN_NOTIFICATION(HttpStatus.FORBIDDEN, ErrorCategory.NOTIFICATION.generate(403_1), "본인의 알림만 처리할 수 있습니다."), + NOT_NOTICE_AUTHOR(HttpStatus.FORBIDDEN, ErrorCategory.NOTIFICATION.generate(403_2), "공지사항 작성자만 수정/삭제할 수 있습니다."); + + private final HttpStatus httpStatus; + private final String code; + private final String message; +} diff --git a/src/main/java/com/daramg/server/post/application/PostService.java b/src/main/java/com/daramg/server/post/application/PostService.java index 86b5ff0..65addee 100644 --- a/src/main/java/com/daramg/server/post/application/PostService.java +++ b/src/main/java/com/daramg/server/post/application/PostService.java @@ -2,6 +2,7 @@ import com.daramg.server.common.application.EntityUtils; import com.daramg.server.common.exception.BusinessException; +import com.daramg.server.post.exception.PostErrorStatus; import com.daramg.server.common.exception.NotFoundException; import com.daramg.server.composer.domain.Composer; import com.daramg.server.composer.repository.ComposerRepository; @@ -61,7 +62,7 @@ public void createCuration(PostCreateDto.CreateCuration dto, User user) { if (dto.getPrimaryComposerId() != null) { primaryComposer = entityUtils.getEntity(dto.getPrimaryComposerId(), Composer.class); } else if (dto.getPostStatus() == PostStatus.PUBLISHED) { - throw new BusinessException("발행 시 주요 작곡가는 필수입니다."); + throw new BusinessException(PostErrorStatus.PRIMARY_COMPOSER_REQUIRED); } List additionalComposers = new ArrayList<>(); @@ -95,7 +96,7 @@ public void createStory(PostCreateDto.CreateStory dto, User user) { if (dto.getPrimaryComposerId() != null) { primaryComposer = entityUtils.getEntity(dto.getPrimaryComposerId(), Composer.class); } else if (dto.getPostStatus() == PostStatus.PUBLISHED) { - throw new BusinessException("발행 시 주요 작곡가는 필수입니다."); + throw new BusinessException(PostErrorStatus.PRIMARY_COMPOSER_REQUIRED); } PostCreateVo.Story vo = new PostCreateVo.Story( user, diff --git a/src/main/java/com/daramg/server/post/exception/PostErrorStatus.java b/src/main/java/com/daramg/server/post/exception/PostErrorStatus.java new file mode 100644 index 0000000..0224a85 --- /dev/null +++ b/src/main/java/com/daramg/server/post/exception/PostErrorStatus.java @@ -0,0 +1,20 @@ +package com.daramg.server.post.exception; + +import com.daramg.server.common.exception.BaseErrorCode; +import com.daramg.server.common.exception.ErrorCategory; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public enum PostErrorStatus implements BaseErrorCode { + + PRIMARY_COMPOSER_REQUIRED(HttpStatus.BAD_REQUEST, ErrorCategory.POST.generate(400_1), "발행 시 주요 작곡가는 필수입니다."), + NOT_POST_AUTHOR(HttpStatus.FORBIDDEN, ErrorCategory.POST.generate(403_1), "포스트 작성자만 수정/삭제할 수 있습니다."); + + private final HttpStatus httpStatus; + private final String code; + private final String message; +} diff --git a/src/main/java/com/daramg/server/post/utils/PostUserValidator.java b/src/main/java/com/daramg/server/post/utils/PostUserValidator.java index 7f73450..5ed64d7 100644 --- a/src/main/java/com/daramg/server/post/utils/PostUserValidator.java +++ b/src/main/java/com/daramg/server/post/utils/PostUserValidator.java @@ -2,13 +2,14 @@ import com.daramg.server.common.exception.BusinessException; import com.daramg.server.post.domain.Post; +import com.daramg.server.post.exception.PostErrorStatus; import com.daramg.server.user.domain.User; public class PostUserValidator { public static void check(Post post, User user) { if (!post.getUser().getId().equals(user.getId())) { - throw new BusinessException("포스트와 작성자가 일치하지 않습니다."); + throw new BusinessException(PostErrorStatus.NOT_POST_AUTHOR); } } } diff --git a/src/main/java/com/daramg/server/user/application/UserService.java b/src/main/java/com/daramg/server/user/application/UserService.java index de0da4c..3c288b7 100644 --- a/src/main/java/com/daramg/server/user/application/UserService.java +++ b/src/main/java/com/daramg/server/user/application/UserService.java @@ -11,6 +11,7 @@ import com.daramg.server.user.dto.PasswordRequestDto; import com.daramg.server.user.dto.UserProfileResponseDto; import com.daramg.server.user.dto.UserProfileUpdateRequestDto; +import com.daramg.server.user.exception.UserErrorStatus; import com.daramg.server.user.repository.UserRepository; import com.daramg.server.user.repository.UserFollowRepository; import lombok.RequiredArgsConstructor; @@ -20,8 +21,6 @@ import java.time.LocalDateTime; -import static com.daramg.server.common.exception.CommonErrorStatus.NOT_FOUND; - @Service @RequiredArgsConstructor public class UserService { @@ -52,12 +51,12 @@ public boolean verifyUserPassword(User user, PasswordRequestDto request) { @Transactional public void changeUserEmail(User user, EmailChangeRequestDto request) { User managedUser = userRepository.findById(user.getId()) - .orElseThrow(() -> new BusinessException("유저를 찾을 수 없습니다.")); - if (managedUser.getEmail().equals(request.getEmail())){ - throw new BusinessException("기존 이메일과 동일한 이메일로 변경할 수 없습니다."); + .orElseThrow(() -> new BusinessException(UserErrorStatus.USER_NOT_FOUND)); + if (managedUser.getEmail().equals(request.getEmail())) { + throw new BusinessException(UserErrorStatus.SAME_EMAIL); } - if (userRepository.existsByEmail(request.getEmail())){ - throw new BusinessException("이미 가입되어 있는 이메일입니다."); + if (userRepository.existsByEmail(request.getEmail())) { + throw new BusinessException(UserErrorStatus.DUPLICATE_EMAIL); } managedUser.changeEmail(request.getEmail()); } @@ -65,15 +64,15 @@ public void changeUserEmail(User user, EmailChangeRequestDto request) { @Transactional public void changeUserPassword(User user, PasswordRequestDto request) { User managedUser = userRepository.findById(user.getId()) - .orElseThrow(() -> new BusinessException("유저를 찾을 수 없습니다.")); + .orElseThrow(() -> new BusinessException(UserErrorStatus.USER_NOT_FOUND)); String encodedPassword = passwordEncoder.encode(request.getPassword()); managedUser.changePassword(encodedPassword); } @Transactional - public void updateUserProfile(User user, UserProfileUpdateRequestDto request){ + public void updateUserProfile(User user, UserProfileUpdateRequestDto request) { User managedUser = userRepository.findById(user.getId()) - .orElseThrow(() -> new BusinessException("유저를 찾을 수 없습니다.")); + .orElseThrow(() -> new BusinessException(UserErrorStatus.USER_NOT_FOUND)); UpdateVo vo = new UpdateVo( request.getProfileImageUrl(), request.getNickname(), @@ -85,17 +84,17 @@ public void updateUserProfile(User user, UserProfileUpdateRequestDto request){ @Transactional public void follow(User follower, Long followedId) { if (follower.getId().equals(followedId)) { - throw new BusinessException("팔로우 대상과 주체의 유저가 동일합니다."); + throw new BusinessException(UserErrorStatus.SELF_FOLLOW); } boolean alreadyFollowing = userFollowRepository .existsByFollowerIdAndFollowedId(follower.getId(), followedId); if (alreadyFollowing) { - throw new BusinessException("이미 팔로우하고 있는 상태입니다."); + throw new BusinessException(UserErrorStatus.ALREADY_FOLLOWING); } User managedFollower = userRepository.findById(follower.getId()) - .orElseThrow(() -> new BusinessException("유저를 찾을 수 없습니다.")); + .orElseThrow(() -> new BusinessException(UserErrorStatus.USER_NOT_FOUND)); User followed = entityUtils.getEntity(followedId, User.class); userFollowRepository.save(UserFollow.of(managedFollower, followed)); @@ -106,16 +105,16 @@ public void follow(User follower, Long followedId) { @Transactional public void unfollow(User follower, Long followedId) { if (follower.getId().equals(followedId)) { - throw new BusinessException("언팔로우 대상과 주체의 유저가 동일합니다."); + throw new BusinessException(UserErrorStatus.SELF_UNFOLLOW); } User managedFollower = userRepository.findById(follower.getId()) - .orElseThrow(() -> new BusinessException("유저를 찾을 수 없습니다.")); + .orElseThrow(() -> new BusinessException(UserErrorStatus.USER_NOT_FOUND)); User followed = entityUtils.getEntity(followedId, User.class); boolean existingFollow = userFollowRepository .existsByFollowerIdAndFollowedId(follower.getId(), followedId); if (!existingFollow) { - throw new BusinessException("언팔로우할 유저를 팔로우하지 않은 상태입니다."); + throw new BusinessException(UserErrorStatus.NOT_FOLLOWING); } userFollowRepository.deleteByFollowerIdAndFollowedId(follower.getId(), followedId); @@ -126,7 +125,7 @@ public void unfollow(User follower, Long followedId) { @Transactional public void withdraw(Long userId) { User user = userRepository.findById(userId) - .orElseThrow(() -> new BusinessException(NOT_FOUND)); + .orElseThrow(() -> new BusinessException(UserErrorStatus.USER_NOT_FOUND)); user.withdraw(); diff --git a/src/main/java/com/daramg/server/user/exception/UserErrorStatus.java b/src/main/java/com/daramg/server/user/exception/UserErrorStatus.java new file mode 100644 index 0000000..3a6c553 --- /dev/null +++ b/src/main/java/com/daramg/server/user/exception/UserErrorStatus.java @@ -0,0 +1,25 @@ +package com.daramg.server.user.exception; + +import com.daramg.server.common.exception.BaseErrorCode; +import com.daramg.server.common.exception.ErrorCategory; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public enum UserErrorStatus implements BaseErrorCode { + + USER_NOT_FOUND(HttpStatus.NOT_FOUND, ErrorCategory.USER.generate(404_1), "유저를 찾을 수 없습니다."), + SAME_EMAIL(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_1), "기존 이메일과 동일한 이메일로 변경할 수 없습니다."), + DUPLICATE_EMAIL(HttpStatus.CONFLICT, ErrorCategory.USER.generate(409_1), "이미 가입되어 있는 이메일입니다."), + SELF_FOLLOW(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_2), "자기 자신을 팔로우할 수 없습니다."), + ALREADY_FOLLOWING(HttpStatus.CONFLICT, ErrorCategory.USER.generate(409_2), "이미 팔로우하고 있는 상태입니다."), + SELF_UNFOLLOW(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_3), "자기 자신을 언팔로우할 수 없습니다."), + NOT_FOLLOWING(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_4), "팔로우하지 않은 유저입니다."); + + private final HttpStatus httpStatus; + private final String code; + private final String message; +} From a57be9d449e137d7fda634e6b8598a79f582f1bf Mon Sep 17 00:00:00 2001 From: Minjae Chung Date: Sat, 21 Feb 2026 22:19:04 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[fix]=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EA=B8=B0=EB=8C=80=20=EB=A9=94=EC=8B=9C=EC=A7=80=EC=99=80=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EC=BD=94=EB=93=9C=20=EB=A9=94=EC=8B=9C?= =?UTF-8?q?=EC=A7=80=20=EB=B6=88=EC=9D=BC=EC=B9=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../daramg/server/comment/application/CommentService.java | 4 ++-- .../daramg/server/comment/exception/CommentErrorStatus.java | 5 +++-- .../notification/exception/NotificationErrorStatus.java | 2 +- .../com/daramg/server/post/exception/PostErrorStatus.java | 2 +- .../com/daramg/server/user/exception/UserErrorStatus.java | 4 ++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/daramg/server/comment/application/CommentService.java b/src/main/java/com/daramg/server/comment/application/CommentService.java index 53a7508..232ab4b 100644 --- a/src/main/java/com/daramg/server/comment/application/CommentService.java +++ b/src/main/java/com/daramg/server/comment/application/CommentService.java @@ -54,7 +54,7 @@ public void createComment(Long postId, CommentCreateDto request, User user){ public void createReply(Long commentId, CommentReplyCreateDto request, User user){ Comment parentComment = entityUtils.getEntity(commentId, Comment.class); if (parentComment.isDeleted() || parentComment.isBlocked()){ - throw new BusinessException(CommentErrorStatus.BLOCKED_OR_DELETED_COMMENT); + throw new BusinessException(CommentErrorStatus.BLOCKED_OR_DELETED_COMMENT_REPLY); } Post post = parentComment.getPost(); if (post.isBlocked()){ @@ -80,7 +80,7 @@ public void createReply(Long commentId, CommentReplyCreateDto request, User user public CommentLikeResponseDto toggleCommentLike(Long commentId, User user){ Comment comment = entityUtils.getEntity(commentId, Comment.class); if (comment.isDeleted() || comment.isBlocked()){ - throw new BusinessException(CommentErrorStatus.BLOCKED_OR_DELETED_COMMENT); + throw new BusinessException(CommentErrorStatus.BLOCKED_OR_DELETED_COMMENT_LIKE); } boolean alreadyLiked = commentLikeRepository diff --git a/src/main/java/com/daramg/server/comment/exception/CommentErrorStatus.java b/src/main/java/com/daramg/server/comment/exception/CommentErrorStatus.java index dcd8b4c..5e08da9 100644 --- a/src/main/java/com/daramg/server/comment/exception/CommentErrorStatus.java +++ b/src/main/java/com/daramg/server/comment/exception/CommentErrorStatus.java @@ -12,9 +12,10 @@ public enum CommentErrorStatus implements BaseErrorCode { BLOCKED_POST(HttpStatus.FORBIDDEN, ErrorCategory.COMMENT.generate(403_1), "블락된 포스트에는 댓글을 남길 수 없습니다."), - BLOCKED_OR_DELETED_COMMENT(HttpStatus.FORBIDDEN, ErrorCategory.COMMENT.generate(403_2), "삭제되었거나 블락된 댓글입니다."), + BLOCKED_OR_DELETED_COMMENT_REPLY(HttpStatus.FORBIDDEN, ErrorCategory.COMMENT.generate(403_2), "삭제되었거나 블락된 댓글에는 대댓글을 남길 수 없습니다."), + BLOCKED_OR_DELETED_COMMENT_LIKE(HttpStatus.FORBIDDEN, ErrorCategory.COMMENT.generate(403_3), "삭제되었거나 블락된 댓글에는 좋아요를 누를 수 없습니다."), ALREADY_DELETED(HttpStatus.BAD_REQUEST, ErrorCategory.COMMENT.generate(400_1), "이미 삭제 처리된 댓글입니다."), - NOT_COMMENT_AUTHOR(HttpStatus.FORBIDDEN, ErrorCategory.COMMENT.generate(403_3), "댓글 작성자만 삭제할 수 있습니다."); + NOT_COMMENT_AUTHOR(HttpStatus.FORBIDDEN, ErrorCategory.COMMENT.generate(403_4), "댓글을 작성한 유저만 댓글을 삭제할 수 있습니다."); private final HttpStatus httpStatus; private final String code; diff --git a/src/main/java/com/daramg/server/notification/exception/NotificationErrorStatus.java b/src/main/java/com/daramg/server/notification/exception/NotificationErrorStatus.java index b83b57a..658d3ee 100644 --- a/src/main/java/com/daramg/server/notification/exception/NotificationErrorStatus.java +++ b/src/main/java/com/daramg/server/notification/exception/NotificationErrorStatus.java @@ -12,7 +12,7 @@ public enum NotificationErrorStatus implements BaseErrorCode { NOT_OWN_NOTIFICATION(HttpStatus.FORBIDDEN, ErrorCategory.NOTIFICATION.generate(403_1), "본인의 알림만 처리할 수 있습니다."), - NOT_NOTICE_AUTHOR(HttpStatus.FORBIDDEN, ErrorCategory.NOTIFICATION.generate(403_2), "공지사항 작성자만 수정/삭제할 수 있습니다."); + NOT_NOTICE_AUTHOR(HttpStatus.FORBIDDEN, ErrorCategory.NOTIFICATION.generate(403_2), "공지사항의 작성자가 일치하지 않습니다."); private final HttpStatus httpStatus; private final String code; diff --git a/src/main/java/com/daramg/server/post/exception/PostErrorStatus.java b/src/main/java/com/daramg/server/post/exception/PostErrorStatus.java index 0224a85..9d09f19 100644 --- a/src/main/java/com/daramg/server/post/exception/PostErrorStatus.java +++ b/src/main/java/com/daramg/server/post/exception/PostErrorStatus.java @@ -12,7 +12,7 @@ public enum PostErrorStatus implements BaseErrorCode { PRIMARY_COMPOSER_REQUIRED(HttpStatus.BAD_REQUEST, ErrorCategory.POST.generate(400_1), "발행 시 주요 작곡가는 필수입니다."), - NOT_POST_AUTHOR(HttpStatus.FORBIDDEN, ErrorCategory.POST.generate(403_1), "포스트 작성자만 수정/삭제할 수 있습니다."); + NOT_POST_AUTHOR(HttpStatus.FORBIDDEN, ErrorCategory.POST.generate(403_1), "포스트와 작성자가 일치하지 않습니다."); private final HttpStatus httpStatus; private final String code; diff --git a/src/main/java/com/daramg/server/user/exception/UserErrorStatus.java b/src/main/java/com/daramg/server/user/exception/UserErrorStatus.java index 3a6c553..8c28277 100644 --- a/src/main/java/com/daramg/server/user/exception/UserErrorStatus.java +++ b/src/main/java/com/daramg/server/user/exception/UserErrorStatus.java @@ -14,9 +14,9 @@ public enum UserErrorStatus implements BaseErrorCode { USER_NOT_FOUND(HttpStatus.NOT_FOUND, ErrorCategory.USER.generate(404_1), "유저를 찾을 수 없습니다."), SAME_EMAIL(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_1), "기존 이메일과 동일한 이메일로 변경할 수 없습니다."), DUPLICATE_EMAIL(HttpStatus.CONFLICT, ErrorCategory.USER.generate(409_1), "이미 가입되어 있는 이메일입니다."), - SELF_FOLLOW(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_2), "자기 자신을 팔로우할 수 없습니다."), + SELF_FOLLOW(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_2), "팔로우 대상과 주체의 유저가 동일합니다."), ALREADY_FOLLOWING(HttpStatus.CONFLICT, ErrorCategory.USER.generate(409_2), "이미 팔로우하고 있는 상태입니다."), - SELF_UNFOLLOW(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_3), "자기 자신을 언팔로우할 수 없습니다."), + SELF_UNFOLLOW(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_3), "언팔로우 대상과 주체의 유저가 동일합니다."), NOT_FOLLOWING(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_4), "팔로우하지 않은 유저입니다."); private final HttpStatus httpStatus; From 4a07aa845a48f6db3b7618d24fb2d84204dd99db Mon Sep 17 00:00:00 2001 From: Minjae Chung Date: Sat, 21 Feb 2026 22:24:12 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[fix]=20NOT=5FFOLLOWING=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B8=B0=EB=8C=80=EA=B0=92=EA=B3=BC=20=EC=9D=BC?= =?UTF-8?q?=EC=B9=98=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/daramg/server/user/exception/UserErrorStatus.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/daramg/server/user/exception/UserErrorStatus.java b/src/main/java/com/daramg/server/user/exception/UserErrorStatus.java index 8c28277..9cd3ef8 100644 --- a/src/main/java/com/daramg/server/user/exception/UserErrorStatus.java +++ b/src/main/java/com/daramg/server/user/exception/UserErrorStatus.java @@ -17,7 +17,7 @@ public enum UserErrorStatus implements BaseErrorCode { SELF_FOLLOW(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_2), "팔로우 대상과 주체의 유저가 동일합니다."), ALREADY_FOLLOWING(HttpStatus.CONFLICT, ErrorCategory.USER.generate(409_2), "이미 팔로우하고 있는 상태입니다."), SELF_UNFOLLOW(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_3), "언팔로우 대상과 주체의 유저가 동일합니다."), - NOT_FOLLOWING(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_4), "팔로우하지 않은 유저입니다."); + NOT_FOLLOWING(HttpStatus.BAD_REQUEST, ErrorCategory.USER.generate(400_4), "언팔로우할 유저를 팔로우하지 않은 상태입니다."); private final HttpStatus httpStatus; private final String code;