diff --git a/src/main/java/flipnote/group/adapter/out/entity/GroupEntity.java b/src/main/java/flipnote/group/adapter/out/entity/GroupEntity.java index 617b559..9aad74f 100644 --- a/src/main/java/flipnote/group/adapter/out/entity/GroupEntity.java +++ b/src/main/java/flipnote/group/adapter/out/entity/GroupEntity.java @@ -6,6 +6,8 @@ import flipnote.group.domain.model.group.Category; import flipnote.group.domain.model.group.JoinPolicy; import flipnote.group.domain.model.group.Visibility; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -110,36 +112,35 @@ public static GroupEntity create(CreateGroupCommand cmd) { */ private static void validate(CreateGroupCommand cmd) { if (cmd == null) { - throw new IllegalArgumentException("command required"); + throw new BusinessException(ErrorCode.INVALID_INPUT); } - if (cmd.name() == null || cmd.name().isBlank()) { - throw new IllegalArgumentException("name required"); + throw new BusinessException(ErrorCode.GROUP_INVALID_NAME); + } + if (cmd.name().length() > 50) { + throw new BusinessException(ErrorCode.GROUP_NAME_TOO_LONG); } if (cmd.maxMember() < 1 || cmd.maxMember() > 100) { - throw new IllegalArgumentException("maxMember invalid"); + throw new BusinessException(ErrorCode.GROUP_INVALID_MAX_MEMBER); } if (cmd.category() == null) { - throw new IllegalArgumentException("category required"); + throw new BusinessException(ErrorCode.GROUP_INVALID_CATEGORY); } if (cmd.joinPolicy() == null) { - throw new IllegalArgumentException("join required"); + throw new BusinessException(ErrorCode.GROUP_INVALID_JOIN_POLICY); } if (cmd.visibility() == null) { - throw new IllegalArgumentException("visibility required"); + throw new BusinessException(ErrorCode.GROUP_INVALID_VISIBILITY); } if (cmd.description() == null || cmd.description().isBlank()) { - throw new IllegalArgumentException("description required"); - } - if (cmd.name().length() > 50) { - throw new IllegalArgumentException("name too long"); + throw new BusinessException(ErrorCode.GROUP_INVALID_DESCRIPTION); } } public void plusCount() { if(this.memberCount+1 > this.maxMember) { - throw new IllegalArgumentException("max member"); + throw new BusinessException(ErrorCode.GROUP_MEMBER_LIMIT_EXCEEDED); } this.memberCount++; @@ -148,7 +149,7 @@ public void plusCount() { public void minusCount() { if(this.memberCount-1 < 0) { - throw new IllegalArgumentException("not minus member"); + throw new BusinessException(ErrorCode.MEMBER_COUNT_UNDERFLOW); } this.memberCount--; diff --git a/src/main/java/flipnote/group/adapter/out/persistence/GroupMemberRepositoryAdapter.java b/src/main/java/flipnote/group/adapter/out/persistence/GroupMemberRepositoryAdapter.java index 2f469f6..70f1b88 100644 --- a/src/main/java/flipnote/group/adapter/out/persistence/GroupMemberRepositoryAdapter.java +++ b/src/main/java/flipnote/group/adapter/out/persistence/GroupMemberRepositoryAdapter.java @@ -11,6 +11,8 @@ import flipnote.group.application.port.out.GroupMemberRepositoryPort; import flipnote.group.domain.model.member.GroupMemberRole; import flipnote.group.domain.model.member.MemberInfo; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import flipnote.group.infrastructure.persistence.jpa.GroupMemberRepository; import flipnote.group.infrastructure.persistence.jpa.GroupRepository; import lombok.RequiredArgsConstructor; @@ -31,7 +33,7 @@ public void save(GroupMemberEntity groupMember) { groupMemberRepository.save(groupMember); GroupEntity groupEntity = groupRepository.findByIdForUpdate(groupMember.getGroupId()).orElseThrow( - () -> new IllegalArgumentException("not exist group") + () -> new BusinessException(ErrorCode.GROUP_NOT_FOUND) ); //그룹 엔티티 + 1 @@ -49,7 +51,7 @@ public void existsUserInGroup(Long groupId, Long userId) { boolean isMember = groupMemberRepository.existsByGroupIdAndUserId(groupId, userId); if(!isMember) { - throw new IllegalArgumentException("user not in Group"); + throw new BusinessException(ErrorCode.USER_NOT_IN_GROUP); } } @@ -72,7 +74,7 @@ public List findMemberInfo(Long groupId) { public boolean checkOwner(Long groupId, Long userId) { GroupMemberEntity groupMember = groupMemberRepository.findByGroupIdAndUserId(groupId, userId).orElseThrow( - () -> new IllegalArgumentException("member not in group") + () -> new BusinessException(ErrorCode.USER_NOT_IN_GROUP) ); return groupMember.getRole().equals(GroupMemberRole.OWNER); @@ -82,7 +84,7 @@ public boolean checkOwner(Long groupId, Long userId) { public GroupMemberEntity findMyRole(Long groupId, Long userId) { GroupMemberEntity entity = groupMemberRepository.findByGroupIdAndUserId(groupId, userId).orElseThrow( - () -> new IllegalArgumentException("entity not exist") + () -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND) ); return entity; @@ -92,14 +94,14 @@ public GroupMemberEntity findMyRole(Long groupId, Long userId) { public void deleteGroupMember(Long memberId) { GroupMemberEntity groupMember = groupMemberRepository.findById(memberId).orElseThrow( - () -> new IllegalArgumentException("not exist member") + () -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND) ); groupMemberRepository.deleteById(memberId); //그룹 인원수 동기화 GroupEntity group = groupRepository.findByIdForUpdate(groupMember.getGroupId()).orElseThrow( - () -> new IllegalArgumentException("not exist group") + () -> new BusinessException(ErrorCode.GROUP_NOT_FOUND) ); group.minusCount(); diff --git a/src/main/java/flipnote/group/adapter/out/persistence/GroupRepositoryAdapter.java b/src/main/java/flipnote/group/adapter/out/persistence/GroupRepositoryAdapter.java index aa6c087..72bd363 100644 --- a/src/main/java/flipnote/group/adapter/out/persistence/GroupRepositoryAdapter.java +++ b/src/main/java/flipnote/group/adapter/out/persistence/GroupRepositoryAdapter.java @@ -8,6 +8,8 @@ import flipnote.group.application.port.out.GroupRepositoryPort; import flipnote.group.domain.model.group.Category; import flipnote.group.domain.model.group.GroupInfo; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import flipnote.group.infrastructure.persistence.jpa.GroupRepository; import lombok.RequiredArgsConstructor; @@ -30,7 +32,7 @@ public Long saveNewGroup(GroupEntity group) { @Override public GroupEntity findById(Long id) { GroupEntity group = groupRepository.findById(id).orElseThrow( - () -> new IllegalArgumentException("Group not Exist") + () -> new BusinessException(ErrorCode.GROUP_NOT_FOUND) ); return group; } @@ -38,7 +40,7 @@ public GroupEntity findById(Long id) { @Override public void delete(Long groupId) { if (!groupRepository.existsById(groupId)) { - throw new IllegalArgumentException("Group not Exist"); + throw new BusinessException(ErrorCode.GROUP_NOT_FOUND); } groupRepository.deleteById(groupId); } @@ -62,7 +64,7 @@ public List findAllByCursorAndCreatedUserId(Long cursorId, Category c public boolean checkJoinable(Long groupId) { GroupEntity groupEntity = groupRepository.findByIdForUpdate(groupId).orElseThrow( - () -> new IllegalArgumentException("not exists") + () -> new BusinessException(ErrorCode.GROUP_NOT_FOUND) ); int maxMember = groupEntity.getMaxMember(); diff --git a/src/main/java/flipnote/group/adapter/out/persistence/GroupRoleRepositoryAdapter.java b/src/main/java/flipnote/group/adapter/out/persistence/GroupRoleRepositoryAdapter.java index 59d38c0..1f8262a 100644 --- a/src/main/java/flipnote/group/adapter/out/persistence/GroupRoleRepositoryAdapter.java +++ b/src/main/java/flipnote/group/adapter/out/persistence/GroupRoleRepositoryAdapter.java @@ -14,6 +14,8 @@ import flipnote.group.application.port.out.GroupRoleRepositoryPort; import flipnote.group.domain.model.member.GroupMemberRole; import flipnote.group.domain.model.permission.GroupPermission; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import flipnote.group.infrastructure.persistence.jpa.GroupMemberRepository; import flipnote.group.infrastructure.persistence.jpa.GroupRolePermissionRepository; import flipnote.group.infrastructure.persistence.jpa.GroupRoleRepository; @@ -90,7 +92,7 @@ public RoleEntity create(Long groupId) { @Override public boolean checkRole(Long userId, Long groupId, GroupMemberRole groupMemberRole) { RoleEntity roleEntity = groupRoleRepository.findByGroupIdAndRole(groupId, groupMemberRole).orElseThrow( - () -> new IllegalArgumentException("not exist role") + () -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND) ); return groupMemberRepository.existsByUserIdAndRole_Id(userId, roleEntity.getId()); } @@ -106,7 +108,7 @@ public boolean checkRole(Long userId, Long groupId, GroupMemberRole groupMemberR public boolean checkPermission(Long userId, Long groupId, GroupPermission permission) { GroupMemberEntity groupMember = groupMemberRepository.findByGroupIdAndUserId(groupId, userId).orElseThrow( - () -> new IllegalArgumentException("not exist member") + () -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND) ); return groupRoleRepository.existsByGroupIdAndRole(groupId, groupMember.getRole().getRole()); @@ -122,7 +124,7 @@ public boolean checkPermission(Long userId, Long groupId, GroupPermission permis public List addPermission(Long groupId, GroupMemberRole role, GroupPermission permission) { RoleEntity roleEntity = groupRoleRepository.findByGroupIdAndRole(groupId, role).orElseThrow( - () -> new IllegalArgumentException("not exist role") + () -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND) ); PermissionEntity permissionEntity = PermissionEntity.builder() @@ -150,7 +152,7 @@ public List addPermission(Long groupId, GroupMemberRole role, G public boolean existPermission(GroupMemberRole role, Long groupId, GroupPermission permission) { RoleEntity roleEntity = groupRoleRepository.findByGroupIdAndRole(groupId, role).orElseThrow( - () -> new IllegalArgumentException("not exist role") + () -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND) ); return groupRolePermissionRepository.existsByGroupRoleIdAndPermission(roleEntity.getId(), permission); @@ -159,14 +161,14 @@ public boolean existPermission(GroupMemberRole role, Long groupId, GroupPermissi @Override public RoleEntity findByIdAndRole(Long id, GroupMemberRole groupMemberRole) { return groupRoleRepository.findByGroupIdAndRole(id, groupMemberRole).orElseThrow( - () -> new IllegalArgumentException("not exist role") + () -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND) ); } @Override public GroupMemberRole findRole(Long userId, Long groupId) { GroupMemberEntity groupMember = groupMemberRepository.findByGroupIdAndUserId(groupId, userId).orElseThrow( - () -> new IllegalArgumentException("not exists member") + () -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND) ); return groupMember.getRole().getRole(); @@ -182,7 +184,7 @@ public GroupMemberRole findRole(Long userId, Long groupId) { @Override public List removePermission(Long groupId, GroupMemberRole role, GroupPermission permission) { RoleEntity roleEntity = groupRoleRepository.findByGroupIdAndRole(groupId, role).orElseThrow( - () -> new IllegalArgumentException("not exists member") + () -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND) ); groupRolePermissionRepository.deleteByGroupRoleIdAndPermission(roleEntity.getId(), permission); @@ -199,7 +201,7 @@ public List removePermission(Long groupId, GroupMemberRole role public List findMyRolePermission(Long groupId, GroupMemberRole role) { RoleEntity roleEntity = groupRoleRepository.findByGroupIdAndRole(groupId, role).orElseThrow( - () -> new IllegalArgumentException("not exists member") + () -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND) ); List permissions = groupRolePermissionRepository.findAllByGroupRoleId( diff --git a/src/main/java/flipnote/group/adapter/out/persistence/JoinRepositoryAdapter.java b/src/main/java/flipnote/group/adapter/out/persistence/JoinRepositoryAdapter.java index ae2f73a..77ae38e 100644 --- a/src/main/java/flipnote/group/adapter/out/persistence/JoinRepositoryAdapter.java +++ b/src/main/java/flipnote/group/adapter/out/persistence/JoinRepositoryAdapter.java @@ -6,6 +6,8 @@ import flipnote.group.adapter.out.entity.JoinEntity; import flipnote.group.application.port.out.JoinRepositoryPort; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import flipnote.group.infrastructure.persistence.jpa.JoinRepository; import lombok.RequiredArgsConstructor; @@ -37,7 +39,7 @@ public List findFormList(Long groupId) { public JoinEntity findJoin(Long joinId) { JoinEntity entity = joinRepository.findById(joinId).orElseThrow( - () -> new IllegalArgumentException("not exist") + () -> new BusinessException(ErrorCode.JOIN_NOT_FOUND) ); return entity; } diff --git a/src/main/java/flipnote/group/api/advice/.gitkeep b/src/main/java/flipnote/group/api/advice/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/flipnote/group/api/advice/ErrorResponse.java b/src/main/java/flipnote/group/api/advice/ErrorResponse.java new file mode 100644 index 0000000..fbad973 --- /dev/null +++ b/src/main/java/flipnote/group/api/advice/ErrorResponse.java @@ -0,0 +1,16 @@ +package flipnote.group.api.advice; + +import flipnote.group.domain.policy.ErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ErrorResponse { + private final String code; + private final String message; + + public static ErrorResponse of(ErrorCode errorCode) { + return new ErrorResponse(errorCode.getCode(), errorCode.getMessage()); + } +} diff --git a/src/main/java/flipnote/group/api/advice/GlobalExceptionHandler.java b/src/main/java/flipnote/group/api/advice/GlobalExceptionHandler.java new file mode 100644 index 0000000..733f5f6 --- /dev/null +++ b/src/main/java/flipnote/group/api/advice/GlobalExceptionHandler.java @@ -0,0 +1,28 @@ +package flipnote.group.api.advice; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; + +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(BusinessException.class) + public ResponseEntity handle(BusinessException e) { + ErrorCode errorCode = e.getErrorCode(); + return ResponseEntity + .status(errorCode.getStatus()) + .body(ErrorResponse.of(errorCode)); + } + + @ExceptionHandler(Exception.class) + public ResponseEntity handle(Exception e) { + return ResponseEntity + .status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ErrorResponse.of(ErrorCode.INTERNAL_SERVER_ERROR)); + } +} diff --git a/src/main/java/flipnote/group/application/service/AddPermissionService.java b/src/main/java/flipnote/group/application/service/AddPermissionService.java index d49af70..e6861af 100644 --- a/src/main/java/flipnote/group/application/service/AddPermissionService.java +++ b/src/main/java/flipnote/group/application/service/AddPermissionService.java @@ -11,6 +11,8 @@ import flipnote.group.application.port.out.GroupRoleRepositoryPort; import flipnote.group.domain.model.member.GroupMemberRole; import flipnote.group.domain.model.permission.GroupPermission; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import lombok.RequiredArgsConstructor; @Service @@ -34,18 +36,18 @@ public AddPermissionResult addPermission(PermissionCommand cmd) { boolean existHostPermission = groupRoleRepository.checkPermission(cmd.userId(), cmd.groupId(), cmd.permission()); if(!existHostPermission) { - throw new IllegalArgumentException("host not exist permission"); + throw new BusinessException(ErrorCode.PERMISSION_DENIED); } //권한이 낮을 경우 if(!role.isHigherThan(cmd.changeRole())) { - throw new IllegalArgumentException("host lower than changeRole"); + throw new BusinessException(ErrorCode.PERMISSION_DENIED); } boolean existPermission = groupRoleRepository.existPermission(cmd.changeRole(), cmd.groupId(), cmd.permission()); if(existPermission) { - throw new IllegalArgumentException("already exist permission"); + throw new BusinessException(ErrorCode.PERMISSION_ALREADY_EXISTS); } List groupPermissions = groupRoleRepository.addPermission(cmd.groupId(), cmd.changeRole(), diff --git a/src/main/java/flipnote/group/application/service/ApplicationFormService.java b/src/main/java/flipnote/group/application/service/ApplicationFormService.java index 0a5fa47..42ef9f1 100644 --- a/src/main/java/flipnote/group/application/service/ApplicationFormService.java +++ b/src/main/java/flipnote/group/application/service/ApplicationFormService.java @@ -23,6 +23,8 @@ import flipnote.group.domain.model.join.JoinStatus; import flipnote.group.domain.model.member.GroupMemberRole; import flipnote.group.domain.model.permission.GroupPermission; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import lombok.RequiredArgsConstructor; @Service @@ -52,7 +54,7 @@ public ApplicationFormResult joinRequest(ApplicationFormCommand cmd) { //이미 가입 신청 여부 if(joinRepository.existsJoin(cmd.groupId(), cmd.userId())) { - throw new IllegalArgumentException("already join"); + throw new BusinessException(ErrorCode.JOIN_ALREADY_EXISTS); } JoinStatus status = JoinStatus.ACCEPT; @@ -85,7 +87,7 @@ public FindJoinFormListResult findJoinFormList(FindJoinFormCommand cmd) { boolean checkPermission = groupRoleRepository.checkPermission(cmd.userId(), cmd.groupId(), JOIN_MANAGE); if(!checkPermission) { - throw new IllegalArgumentException("not permission"); + throw new BusinessException(ErrorCode.PERMISSION_DENIED); } List joinDomainList = joinRepository.findFormList(cmd.groupId()); @@ -97,12 +99,12 @@ public FindJoinFormListResult findJoinFormList(FindJoinFormCommand cmd) { private void checkJoinable(GroupEntity group) { //비공개 그룹 인지 확인 if(group.getVisibility().equals(Visibility.PRIVATE)) { - throw new IllegalArgumentException("private group"); + throw new BusinessException(ErrorCode.GROUP_PRIVATE); } //멤버가 최대인 경우 if(group.getMemberCount() >= group.getMaxMember()) { - throw new IllegalArgumentException("max member"); + throw new BusinessException(ErrorCode.GROUP_MEMBER_LIMIT_EXCEEDED); } } } diff --git a/src/main/java/flipnote/group/application/service/ChangeGroupService.java b/src/main/java/flipnote/group/application/service/ChangeGroupService.java index c48eba7..a8f4e5d 100644 --- a/src/main/java/flipnote/group/application/service/ChangeGroupService.java +++ b/src/main/java/flipnote/group/application/service/ChangeGroupService.java @@ -9,6 +9,8 @@ import flipnote.group.application.port.in.command.ChangeGroupCommand; import flipnote.group.application.port.in.result.ChangeGroupResult; import flipnote.group.domain.model.member.GroupMemberRole; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import flipnote.group.infrastructure.persistence.jpa.GroupRepository; import flipnote.image.grpc.v1.GetUrlByReferenceRequest; import flipnote.image.grpc.v1.GetUrlByReferenceResponse; @@ -34,14 +36,14 @@ public class ChangeGroupService implements ChangeGroupUseCase { public ChangeGroupResult change(ChangeGroupCommand cmd) { GroupEntity entity = jpaGroupRepository.findById(cmd.groupId()).orElseThrow( - () -> new IllegalArgumentException("group not Exists") + () -> new BusinessException(ErrorCode.GROUP_NOT_FOUND) ); //오너 인지 확인 boolean isOwner = groupRoleRepository.checkRole(cmd.userId(), entity.getId(), GroupMemberRole.OWNER); if(!isOwner) { - throw new IllegalArgumentException("not owner"); + throw new BusinessException(ErrorCode.NOT_OWNER); } entity.change(cmd); diff --git a/src/main/java/flipnote/group/application/service/CreateGroupService.java b/src/main/java/flipnote/group/application/service/CreateGroupService.java index 196ef08..46c0a88 100644 --- a/src/main/java/flipnote/group/application/service/CreateGroupService.java +++ b/src/main/java/flipnote/group/application/service/CreateGroupService.java @@ -12,6 +12,8 @@ import flipnote.group.application.port.out.GroupMemberRepositoryPort; import flipnote.group.application.port.out.GroupRepositoryPort; import flipnote.group.application.port.out.GroupRoleRepositoryPort; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import flipnote.image.grpc.v1.ActivateImageRequest; import flipnote.image.grpc.v1.ActivateImageResponse; import flipnote.image.grpc.v1.GetUrlByReferenceRequest; @@ -63,10 +65,10 @@ public CreateGroupResult create(CreateGroupCommand cmd) { imageCommandServiceStub.activateImage(request); } catch (StatusRuntimeException e) { switch (e.getStatus().getCode()) { - case NOT_FOUND -> throw new IllegalArgumentException("이미지를 찾을 수 없습니다."); - case INVALID_ARGUMENT -> throw new IllegalArgumentException("잘못된 요청입니다."); - case INTERNAL -> throw new IllegalArgumentException("이미지 서버 내부 오류입니다."); - default -> throw new IllegalArgumentException("이미지 서비스 오류: " + e.getStatus().getDescription()); + case NOT_FOUND -> throw new BusinessException(ErrorCode.IMAGE_NOT_FOUND); + case INVALID_ARGUMENT -> throw new BusinessException(ErrorCode.IMAGE_INVALID_REQUEST); + case INTERNAL -> throw new BusinessException(ErrorCode.IMAGE_SERVER_ERROR); + default -> throw new BusinessException(ErrorCode.IMAGE_SERVICE_ERROR); } } diff --git a/src/main/java/flipnote/group/application/service/DeleteGroupService.java b/src/main/java/flipnote/group/application/service/DeleteGroupService.java index 5c6ea6e..574919f 100644 --- a/src/main/java/flipnote/group/application/service/DeleteGroupService.java +++ b/src/main/java/flipnote/group/application/service/DeleteGroupService.java @@ -8,6 +8,8 @@ import flipnote.group.application.port.out.GroupRepositoryPort; import flipnote.group.application.port.out.GroupRoleRepositoryPort; import flipnote.group.domain.model.member.GroupMemberRole; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import lombok.RequiredArgsConstructor; @Service @@ -26,7 +28,7 @@ public void deleteGroup(DeleteGroupCommand cmd) { //오너가 아닐 경우 에러 발생 if(!isOwner) { - throw new IllegalArgumentException("not owner"); + throw new BusinessException(ErrorCode.NOT_OWNER); } groupRepository.delete(cmd.groupId()); diff --git a/src/main/java/flipnote/group/application/service/FindGroupNameService.java b/src/main/java/flipnote/group/application/service/FindGroupNameService.java index 203165e..cf6eb33 100644 --- a/src/main/java/flipnote/group/application/service/FindGroupNameService.java +++ b/src/main/java/flipnote/group/application/service/FindGroupNameService.java @@ -7,6 +7,8 @@ import flipnote.group.adapter.out.entity.GroupEntity; import flipnote.group.application.port.in.FindGroupNameUseCase; import flipnote.group.application.port.out.GroupRepositoryPort; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import lombok.RequiredArgsConstructor; @Service @@ -26,7 +28,7 @@ public String findGroupName(Long groupId) { GroupEntity group = groupRepository.findById(groupId); if (group == null) { - throw new NoSuchElementException("Group not found: " + groupId); + throw new BusinessException(ErrorCode.GROUP_NOT_FOUND); } return group.getName(); diff --git a/src/main/java/flipnote/group/application/service/FindGroupService.java b/src/main/java/flipnote/group/application/service/FindGroupService.java index 54d351f..9ef8eff 100644 --- a/src/main/java/flipnote/group/application/service/FindGroupService.java +++ b/src/main/java/flipnote/group/application/service/FindGroupService.java @@ -14,6 +14,8 @@ import flipnote.group.application.port.in.result.FindGroupResult; import flipnote.group.application.port.out.GroupMemberRepositoryPort; import flipnote.group.application.port.out.GroupRepositoryPort; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import flipnote.image.grpc.v1.GetUrlByReferenceRequest; import flipnote.image.grpc.v1.GetUrlByReferenceResponse; import flipnote.image.grpc.v1.ImageCommandServiceGrpc; @@ -56,9 +58,10 @@ public FindGroupResult findGroup(FindGroupCommand cmd) { imageUrl = response.getImageUrl(); } catch (StatusRuntimeException e) { switch (e.getStatus().getCode()) { - case NOT_FOUND -> throw new IllegalArgumentException("이미지를 찾을 수 없습니다."); - case INTERNAL -> throw new IllegalArgumentException("이미지 서버 내부 오류입니다."); - default -> throw new IllegalArgumentException("이미지 서비스 오류: " + e.getStatus().getDescription()); + case NOT_FOUND -> throw new BusinessException(ErrorCode.IMAGE_NOT_FOUND); + case INVALID_ARGUMENT -> throw new BusinessException(ErrorCode.IMAGE_INVALID_REQUEST); + case INTERNAL -> throw new BusinessException(ErrorCode.IMAGE_SERVER_ERROR); + default -> throw new BusinessException(ErrorCode.IMAGE_SERVICE_ERROR); } } diff --git a/src/main/java/flipnote/group/application/service/JoinRespondService.java b/src/main/java/flipnote/group/application/service/JoinRespondService.java index 0c2a226..84ef6eb 100644 --- a/src/main/java/flipnote/group/application/service/JoinRespondService.java +++ b/src/main/java/flipnote/group/application/service/JoinRespondService.java @@ -16,6 +16,8 @@ import flipnote.group.domain.model.join.JoinStatus; import flipnote.group.domain.model.member.GroupMemberRole; import flipnote.group.domain.model.permission.GroupPermission; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import lombok.RequiredArgsConstructor; @Service @@ -42,13 +44,13 @@ public JoinRespondResult joinRespond(JoinRespondCommand cmd) { boolean existPermission = groupRoleRepository.checkPermission(cmd.userId(), cmd.groupId(), MANAGE); if(!existPermission) { - throw new IllegalArgumentException("not permission"); + throw new BusinessException(ErrorCode.PERMISSION_NOT_FOUND); } JoinEntity join = joinRepository.findJoin(cmd.joinId()); if(join.getStatus().equals(JoinStatus.ACCEPT)) { - throw new IllegalArgumentException("already accept"); + throw new BusinessException(ErrorCode.JOIN_ALREADY_ACCEPTED); } join.updateStatus(cmd.status()); @@ -65,7 +67,7 @@ public JoinRespondResult joinRespond(JoinRespondCommand cmd) { //꽉찼을 경우 if(!joinable) { - throw new IllegalArgumentException("max member"); + throw new BusinessException(ErrorCode.GROUP_MEMBER_LIMIT_EXCEEDED); } //가입 가능한 경우 diff --git a/src/main/java/flipnote/group/application/service/KickMemberService.java b/src/main/java/flipnote/group/application/service/KickMemberService.java index 3eb446c..40246ce 100644 --- a/src/main/java/flipnote/group/application/service/KickMemberService.java +++ b/src/main/java/flipnote/group/application/service/KickMemberService.java @@ -8,6 +8,8 @@ import flipnote.group.application.port.out.GroupMemberRepositoryPort; import flipnote.group.application.port.out.GroupRoleRepositoryPort; import flipnote.group.domain.model.permission.GroupPermission; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import lombok.RequiredArgsConstructor; @Service @@ -23,13 +25,13 @@ public void kickMember(KickMemberCommand cmd) { //권한 체크 boolean hasPermission = groupRoleRepository.checkPermission(cmd.userId(), cmd.groupId(), GroupPermission.MEMBER_MANAGE); if(!hasPermission) { - throw new IllegalArgumentException("not exist permission"); + throw new BusinessException(ErrorCode.PERMISSION_DENIED); } boolean isExist = groupMemberRepository.checkMember(cmd.memberId()); if(!isExist) { - throw new IllegalArgumentException("not exist member"); + throw new BusinessException(ErrorCode.MEMBER_NOT_FOUND); } groupMemberRepository.deleteGroupMember(cmd.memberId()); diff --git a/src/main/java/flipnote/group/application/service/RemovePermissionService.java b/src/main/java/flipnote/group/application/service/RemovePermissionService.java index 5c9ce69..7c563c6 100644 --- a/src/main/java/flipnote/group/application/service/RemovePermissionService.java +++ b/src/main/java/flipnote/group/application/service/RemovePermissionService.java @@ -11,6 +11,8 @@ import flipnote.group.application.port.out.GroupRoleRepositoryPort; import flipnote.group.domain.model.member.GroupMemberRole; import flipnote.group.domain.model.permission.GroupPermission; +import flipnote.group.domain.policy.BusinessException; +import flipnote.group.domain.policy.ErrorCode; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -31,21 +33,21 @@ public RemovePermissionResult removePermission(PermissionCommand cmd) { log.debug("{} {}", role, cmd.changeRole()); if(!role.isHigherThan(cmd.changeRole())) { - throw new IllegalArgumentException("host lower than changeRole"); + throw new BusinessException(ErrorCode.PERMISSION_ROLE_TOO_LOW); } //호스트의 권한이 있는지 boolean existHostPermission = groupRoleRepository.checkPermission(cmd.userId(), cmd.groupId(), cmd.permission()); if(!existHostPermission) { - throw new IllegalArgumentException("host not exist permission"); + throw new BusinessException(ErrorCode.PERMISSION_HOST_NOT_FOUND); } //바꿀 역할의 권한이 있는지 확인 boolean existPermission = groupRoleRepository.existPermission(cmd.changeRole(), cmd.groupId(), cmd.permission()); if(!existPermission) { - throw new IllegalArgumentException("role not exist permission"); + throw new BusinessException(ErrorCode.PERMISSION_NOT_FOUND); } List groupPermissions = groupRoleRepository.removePermission(cmd.groupId(), cmd.changeRole(), diff --git a/src/main/java/flipnote/group/domain/policy/.gitkeep b/src/main/java/flipnote/group/domain/policy/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/flipnote/group/domain/policy/BusinessException.java b/src/main/java/flipnote/group/domain/policy/BusinessException.java new file mode 100644 index 0000000..2389605 --- /dev/null +++ b/src/main/java/flipnote/group/domain/policy/BusinessException.java @@ -0,0 +1,14 @@ +package flipnote.group.domain.policy; + +import lombok.Getter; + +@Getter +public class BusinessException extends RuntimeException { + + private final ErrorCode errorCode; + + public BusinessException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode = errorCode; + } +} diff --git a/src/main/java/flipnote/group/domain/policy/ErrorCode.java b/src/main/java/flipnote/group/domain/policy/ErrorCode.java new file mode 100644 index 0000000..01c4549 --- /dev/null +++ b/src/main/java/flipnote/group/domain/policy/ErrorCode.java @@ -0,0 +1,58 @@ +package flipnote.group.domain.policy; + +import org.springframework.http.HttpStatus; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum ErrorCode { + + // Group + GROUP_NOT_FOUND(HttpStatus.NOT_FOUND, "GROUP_001", "그룹을 찾을 수 없습니다"), + GROUP_ALREADY_EXISTS(HttpStatus.CONFLICT, "GROUP_002", "이미 존재하는 그룹입니다"), + GROUP_MEMBER_LIMIT_EXCEEDED(HttpStatus.BAD_REQUEST, "GROUP_003", "그룹 인원이 초과되었습니다"), + GROUP_PRIVATE(HttpStatus.FORBIDDEN, "GROUP_004", "비공개 그룹입니다"), + GROUP_INVALID_NAME(HttpStatus.BAD_REQUEST, "GROUP_005", "그룹 이름이 유효하지 않습니다"), + GROUP_NAME_TOO_LONG(HttpStatus.BAD_REQUEST, "GROUP_006", "그룹 이름이 너무 깁니다"), + GROUP_INVALID_MAX_MEMBER(HttpStatus.BAD_REQUEST, "GROUP_007", "최대 멤버 수가 유효하지 않습니다"), + GROUP_INVALID_CATEGORY(HttpStatus.BAD_REQUEST, "GROUP_008", "카테고리가 유효하지 않습니다"), + GROUP_INVALID_JOIN_POLICY(HttpStatus.BAD_REQUEST, "GROUP_009", "가입 정책이 유효하지 않습니다"), + GROUP_INVALID_VISIBILITY(HttpStatus.BAD_REQUEST, "GROUP_010", "공개 여부가 유효하지 않습니다"), + GROUP_INVALID_DESCRIPTION(HttpStatus.BAD_REQUEST, "GROUP_011", "그룹 설명이 유효하지 않습니다"), + + // Member + MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "MEMBER_001", "멤버를 찾을 수 없습니다"), + MEMBER_ALREADY_JOINED(HttpStatus.CONFLICT, "MEMBER_002", "이미 가입된 멤버입니다"), + USER_NOT_IN_GROUP(HttpStatus.NOT_FOUND, "MEMBER_003", "유저가 그룹의 멤버가 아닙니다"), + MEMBER_COUNT_UNDERFLOW(HttpStatus.BAD_REQUEST, "MEMBER_004", "멤버 수가 0 미만이 될 수 없습니다"), + + // Permission + PERMISSION_DENIED(HttpStatus.FORBIDDEN, "PERM_001", "권한이 없습니다"), + PERMISSION_ALREADY_EXISTS(HttpStatus.CONFLICT, "PERM_002", "이미 존재하는 권한입니다"), + PERMISSION_NOT_FOUND(HttpStatus.NOT_FOUND, "PERM_003", "권한을 찾을 수 없습니다"), + PERMISSION_HOST_NOT_FOUND(HttpStatus.NOT_FOUND, "PERM_004", "호스트 권한이 존재하지 않습니다"), + PERMISSION_ROLE_TOO_LOW(HttpStatus.FORBIDDEN, "PERM_005", "변경하려는 역할보다 권한이 낮습니다"), + NOT_OWNER(HttpStatus.FORBIDDEN, "PERM_006", "그룹 오너가 아닙니다"), + + // Join + JOIN_NOT_FOUND(HttpStatus.NOT_FOUND, "JOIN_001", "가입 신청을 찾을 수 없습니다"), + JOIN_ALREADY_EXISTS(HttpStatus.CONFLICT, "JOIN_002", "이미 가입 신청이 존재합니다"), + JOIN_ALREADY_ACCEPTED(HttpStatus.CONFLICT, "JOIN_003", "이미 수락된 가입 신청입니다"), + JOIN_NOT_JOINABLE(HttpStatus.BAD_REQUEST, "JOIN_004", "가입이 불가능한 상태입니다"), + + // Image (gRPC) + IMAGE_NOT_FOUND(HttpStatus.NOT_FOUND, "IMAGE_001", "이미지를 찾을 수 없습니다"), + IMAGE_INVALID_REQUEST(HttpStatus.BAD_REQUEST, "IMAGE_002", "잘못된 이미지 요청입니다"), + IMAGE_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "IMAGE_003", "이미지 서버 내부 오류입니다"), + IMAGE_SERVICE_ERROR(HttpStatus.BAD_GATEWAY, "IMAGE_004", "이미지 서비스 오류입니다"), + + // Common + INVALID_INPUT(HttpStatus.BAD_REQUEST, "COMMON_001", "잘못된 입력입니다"), + INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "COMMON_002", "서버 오류가 발생했습니다"); + + private final HttpStatus status; + private final String code; + private final String message; +}