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..232ab4b 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_REPLY); } 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_LIKE); } 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..5e08da9 --- /dev/null +++ b/src/main/java/com/daramg/server/comment/exception/CommentErrorStatus.java @@ -0,0 +1,23 @@ +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_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_4), "댓글을 작성한 유저만 댓글을 삭제할 수 있습니다."); + + 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..658d3ee --- /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..9d09f19 --- /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..9cd3ef8 --- /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; +}