From 63c93dfde04849a6c855c6bb0bd26af98821351f Mon Sep 17 00:00:00 2001 From: Juhwan Kim <13selfesteem91@naver.com> Date: Thu, 8 Aug 2024 10:50:29 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EC=97=90=EB=9F=AC=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=AC=EC=A0=95=EC=9D=98=20(#227)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 에러 코드 재정의 Co-authored-by: 3juhwan <13selfesteem91@naver.com> * fix: 변수를 받는 예외 메세지 수정 Co-authored-by: 3juhwan <13selfesteem91@naver.com> --------- Co-authored-by: kunsanglee Co-authored-by: Arachne <66822642+Arachneee@users.noreply.github.com> --- .../haengdong/application/ActionService.java | 2 +- .../haengdong/application/AuthService.java | 3 +- .../application/BillActionService.java | 8 +-- .../haengdong/application/EventService.java | 6 +- .../application/MemberActionFactory.java | 3 +- .../application/MemberActionService.java | 10 +-- .../haengdong/config/AdminInterceptor.java | 3 +- .../haengdong/domain/action/BillAction.java | 14 ++-- .../domain/action/CurrentMembers.java | 4 +- .../haengdong/domain/action/MemberAction.java | 14 ++++ .../domain/action/MemberActionStatus.java | 4 +- .../server/haengdong/domain/event/Event.java | 15 ++-- .../exception/AuthenticationException.java | 15 ++++ .../haengdong/exception/ErrorResponse.java | 8 +-- .../exception/GlobalExceptionHandler.java | 6 +- .../exception/HaengdongErrorCode.java | 70 ++++++++++++++----- .../exception/HaengdongException.java | 10 +-- .../auth/AuthenticationExtractor.java | 5 +- .../request/BillActionSaveRequest.java | 4 +- .../request/BillActionUpdateRequest.java | 10 +-- .../request/BillActionsSaveRequest.java | 5 +- .../request/EventLoginRequest.java | 8 +-- .../request/EventSaveRequest.java | 4 +- .../request/MemberActionsSaveRequest.java | 2 +- .../request/MemberUpdateRequest.java | 4 +- .../application/ActionServiceTest.java | 2 +- .../domain/action/BillActionTest.java | 6 +- .../haengdong/domain/event/EventTest.java | 4 +- .../BillActionControllerTest.java | 2 +- 29 files changed, 156 insertions(+), 95 deletions(-) diff --git a/server/src/main/java/server/haengdong/application/ActionService.java b/server/src/main/java/server/haengdong/application/ActionService.java index bda638756..824b5afb9 100644 --- a/server/src/main/java/server/haengdong/application/ActionService.java +++ b/server/src/main/java/server/haengdong/application/ActionService.java @@ -24,7 +24,7 @@ public class ActionService { public List getMemberBillReports(String token) { Event event = eventRepository.findByToken(token) - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_EVENT)); + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.EVENT_NOT_FOUND)); List billActions = billActionRepository.findByAction_Event(event); List memberActions = memberActionRepository.findAllByEvent(event); diff --git a/server/src/main/java/server/haengdong/application/AuthService.java b/server/src/main/java/server/haengdong/application/AuthService.java index 6a22fcbe2..d9352ad53 100644 --- a/server/src/main/java/server/haengdong/application/AuthService.java +++ b/server/src/main/java/server/haengdong/application/AuthService.java @@ -4,6 +4,7 @@ import java.util.Map; import server.haengdong.domain.TokenProvider; import server.haengdong.exception.AuthenticationException; +import server.haengdong.exception.HaengdongErrorCode; public class AuthService { @@ -30,7 +31,7 @@ public String findEventIdByToken(String token) { private void validateToken(String token) { if (!tokenProvider.validateToken(token)) { - throw new AuthenticationException(); + throw new AuthenticationException(HaengdongErrorCode.TOKEN_INVALID); } } diff --git a/server/src/main/java/server/haengdong/application/BillActionService.java b/server/src/main/java/server/haengdong/application/BillActionService.java index 68abb466e..468508d07 100644 --- a/server/src/main/java/server/haengdong/application/BillActionService.java +++ b/server/src/main/java/server/haengdong/application/BillActionService.java @@ -45,7 +45,7 @@ private Action createStartAction(Event event) { @Transactional public void updateBillAction(String token, Long actionId, BillActionUpdateAppRequest request) { BillAction billAction = billActionRepository.findByAction_Id(actionId) - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_BILL_ACTION)); + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.BILL_ACTION_NOT_FOUND)); validateToken(token, billAction); @@ -56,19 +56,19 @@ public void updateBillAction(String token, Long actionId, BillActionUpdateAppReq private void validateToken(String token, BillAction billAction) { Event event = billAction.getEvent(); if (event.isTokenMismatch(token)) { - throw new HaengdongException(HaengdongErrorCode.NOT_FOUND_BILL_ACTION); + throw new HaengdongException(HaengdongErrorCode.BILL_ACTION_NOT_FOUND); } } private Event getEvent(String eventToken) { return eventRepository.findByToken(eventToken) - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_EVENT)); + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.EVENT_NOT_FOUND)); } @Transactional public void deleteBillAction(String token, Long actionId) { Event event = eventRepository.findByToken(token) - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_EVENT)); + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.EVENT_NOT_FOUND)); billActionRepository.deleteByAction_EventAndActionId(event, actionId); } diff --git a/server/src/main/java/server/haengdong/application/EventService.java b/server/src/main/java/server/haengdong/application/EventService.java index 01f198571..3408a6215 100644 --- a/server/src/main/java/server/haengdong/application/EventService.java +++ b/server/src/main/java/server/haengdong/application/EventService.java @@ -112,19 +112,19 @@ public void updateMember(String token, String memberName, MemberUpdateAppRequest private void validateMemberNameUnique(Event event, String updatedMemberName) { boolean isMemberNameExist = memberActionRepository.existsByAction_EventAndMemberName(event, updatedMemberName); if (isMemberNameExist) { - throw new HaengdongException(HaengdongErrorCode.DUPLICATED_MEMBER_NAME); + throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_DUPLICATE); } } public void validatePassword(EventLoginAppRequest request) throws HaengdongException { Event event = getEvent(request.token()); if (event.isSamePassword(request.password())) { - throw new AuthenticationException(); + throw new AuthenticationException(HaengdongErrorCode.PASSWORD_INVALID); } } private Event getEvent(String token) { return eventRepository.findByToken(token) - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_EVENT)); + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.EVENT_NOT_FOUND)); } } diff --git a/server/src/main/java/server/haengdong/application/MemberActionFactory.java b/server/src/main/java/server/haengdong/application/MemberActionFactory.java index 9d9afb6ac..c0a171642 100644 --- a/server/src/main/java/server/haengdong/application/MemberActionFactory.java +++ b/server/src/main/java/server/haengdong/application/MemberActionFactory.java @@ -1,7 +1,6 @@ package server.haengdong.application; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -48,7 +47,7 @@ private void validateMemberNames(MemberActionsSaveAppRequest request) { long uniqueCount = memberNames.stream().distinct().count(); if (uniqueCount != memberNames.size()) { - throw new HaengdongException(HaengdongErrorCode.DUPLICATED_MEMBER_ACTION); + throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_DUPLICATE); } } diff --git a/server/src/main/java/server/haengdong/application/MemberActionService.java b/server/src/main/java/server/haengdong/application/MemberActionService.java index 749771259..3fef4deb4 100644 --- a/server/src/main/java/server/haengdong/application/MemberActionService.java +++ b/server/src/main/java/server/haengdong/application/MemberActionService.java @@ -56,12 +56,12 @@ public List getCurrentMembers(String token) { private Event findEvent(String token) { return eventRepository.findByToken(token) - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_EVENT)); + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.EVENT_NOT_FOUND)); } public void deleteMember(String token, String memberName) { Event event = eventRepository.findByToken(token) - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_EVENT)); + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.EVENT_NOT_FOUND)); memberActionRepository.deleteAllByEventAndMemberName(event, memberName); } @@ -69,11 +69,11 @@ public void deleteMember(String token, String memberName) { @Transactional public void deleteMemberAction(String token, Long actionId) { Event event = eventRepository.findByToken(token) - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_EVENT)); + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.EVENT_NOT_FOUND)); Action action = actionRepository.findByIdAndEvent(actionId, event) - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_ACTION)); + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.ACTION_NOT_FOUND)); MemberAction memberAction = memberActionRepository.findByAction(action) - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_MEMBER_ACTION)); + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.MEMBER_ACTION_NOT_FOUND)); memberActionRepository.deleteAllByMemberNameAndMinSequence(memberAction.getMemberName(), memberAction.getSequence()); diff --git a/server/src/main/java/server/haengdong/config/AdminInterceptor.java b/server/src/main/java/server/haengdong/config/AdminInterceptor.java index c3ca1c943..af24b783b 100644 --- a/server/src/main/java/server/haengdong/config/AdminInterceptor.java +++ b/server/src/main/java/server/haengdong/config/AdminInterceptor.java @@ -7,6 +7,7 @@ import org.springframework.web.servlet.HandlerInterceptor; import server.haengdong.application.AuthService; import server.haengdong.exception.AuthenticationException; +import server.haengdong.exception.HaengdongErrorCode; import server.haengdong.infrastructure.auth.AuthenticationExtractor; @Slf4j @@ -39,7 +40,7 @@ private void validateToken(HttpServletRequest request) { String tokenEventId = authService.findEventIdByToken(token); String eventId = request.getRequestURI().split("/")[3]; if (!tokenEventId.equals(eventId)) { - throw new AuthenticationException(); + throw new AuthenticationException(HaengdongErrorCode.FORBIDDEN); } } } diff --git a/server/src/main/java/server/haengdong/domain/action/BillAction.java b/server/src/main/java/server/haengdong/domain/action/BillAction.java index 738b04d39..1a50db47d 100644 --- a/server/src/main/java/server/haengdong/domain/action/BillAction.java +++ b/server/src/main/java/server/haengdong/domain/action/BillAction.java @@ -20,10 +20,10 @@ @Entity public class BillAction implements Comparable { - private static final int MIN_TITLE_LENGTH = 2; - private static final int MAX_TITLE_LENGTH = 30; - private static final long MIN_PRICE = 1L; - private static final long MAX_PRICE = 10_000_000L; + public static final int MIN_TITLE_LENGTH = 1; + public static final int MAX_TITLE_LENGTH = 30; + public static final long MIN_PRICE = 1L; + public static final long MAX_PRICE = 10_000_000L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -53,15 +53,13 @@ private BillAction(Long id, Action action, String title, Long price) { private void validateTitle(String title) { int titleLength = title.trim().length(); if (titleLength < MIN_TITLE_LENGTH || titleLength > MAX_TITLE_LENGTH) { - throw new HaengdongException(HaengdongErrorCode.BAD_REQUEST, - String.format("앞뒤 공백을 제거한 지출 내역 제목은 %d ~ %d자여야 합니다.", MIN_TITLE_LENGTH, MAX_TITLE_LENGTH)); + throw new HaengdongException(HaengdongErrorCode.BILL_ACTION_TITLE_INVALID); } } private void validatePrice(Long price) { if (price < MIN_PRICE || price > MAX_PRICE) { - throw new HaengdongException(HaengdongErrorCode.BAD_REQUEST, - String.format("지출 금액은 %,d 이하의 자연수여야 합니다.", MAX_PRICE)); + throw new HaengdongException(HaengdongErrorCode.BILL_ACTION_PRICE_INVALID); } } diff --git a/server/src/main/java/server/haengdong/domain/action/CurrentMembers.java b/server/src/main/java/server/haengdong/domain/action/CurrentMembers.java index 082b9139d..7706c05d1 100644 --- a/server/src/main/java/server/haengdong/domain/action/CurrentMembers.java +++ b/server/src/main/java/server/haengdong/domain/action/CurrentMembers.java @@ -56,10 +56,10 @@ public CurrentMembers addMemberAction(MemberAction memberAction) { public void validate(String memberName, MemberActionStatus memberActionStatus) { if (memberActionStatus == MemberActionStatus.IN && members.contains(memberName)) { - throw new HaengdongException(HaengdongErrorCode.INVALID_MEMBER_IN_ACTION); + throw new HaengdongException(HaengdongErrorCode.MEMBER_ALREADY_EXIST); } if (memberActionStatus == MemberActionStatus.OUT && !members.contains(memberName)) { - throw new HaengdongException(HaengdongErrorCode.INVALID_MEMBER_OUT_ACTION); + throw new HaengdongException(HaengdongErrorCode.MEMBER_NOT_EXIST); } } diff --git a/server/src/main/java/server/haengdong/domain/action/MemberAction.java b/server/src/main/java/server/haengdong/domain/action/MemberAction.java index 1e78820b2..3faf65bde 100644 --- a/server/src/main/java/server/haengdong/domain/action/MemberAction.java +++ b/server/src/main/java/server/haengdong/domain/action/MemberAction.java @@ -12,12 +12,17 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import server.haengdong.exception.HaengdongErrorCode; +import server.haengdong.exception.HaengdongException; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity public class MemberAction implements Comparable { + public static final int MIN_NAME_LENGTH = 1; + public static final int MAX_NAME_LENGTH = 4; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -33,13 +38,22 @@ public class MemberAction implements Comparable { private Long memberGroupId; public MemberAction(Action action, String memberName, MemberActionStatus status, Long memberGroupId) { + validateMemberName(memberName); this.action = action; this.memberName = memberName; this.status = status; this.memberGroupId = memberGroupId; } + private void validateMemberName(String memberName) { + int memberLength = memberName.length(); + if (memberLength < MIN_NAME_LENGTH || memberLength > MAX_NAME_LENGTH) { + throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_LENGTH_INVALID); + } + } + public void updateMemberName(String memberName) { + validateMemberName(memberName); this.memberName = memberName; } diff --git a/server/src/main/java/server/haengdong/domain/action/MemberActionStatus.java b/server/src/main/java/server/haengdong/domain/action/MemberActionStatus.java index 0a20817fd..76c5a66d4 100644 --- a/server/src/main/java/server/haengdong/domain/action/MemberActionStatus.java +++ b/server/src/main/java/server/haengdong/domain/action/MemberActionStatus.java @@ -13,7 +13,7 @@ public static MemberActionStatus of(String status) { return Arrays.stream(MemberActionStatus.values()) .filter(s -> s.name().equals(status)) .findFirst() - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.BAD_REQUEST, - "존재하지 않는 인원 변동 액션입니다.")); + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.MEMBER_ACTION_STATUS_INVALID, + String.format(HaengdongErrorCode.MEMBER_ACTION_STATUS_INVALID.getMessage(), status))); } } diff --git a/server/src/main/java/server/haengdong/domain/event/Event.java b/server/src/main/java/server/haengdong/domain/event/Event.java index f43145f0d..e90becb3c 100644 --- a/server/src/main/java/server/haengdong/domain/event/Event.java +++ b/server/src/main/java/server/haengdong/domain/event/Event.java @@ -17,10 +17,11 @@ @Entity public class Event { - private static final int MIN_NAME_LENGTH = 2; - private static final int MAX_NAME_LENGTH = 20; + public static final int MIN_NAME_LENGTH = 1; + public static final int MAX_NAME_LENGTH = 20; + public static final int PASSWORD_LENGTH = 4; private static final String SPACES = " "; - private static final Pattern PASSWORD_PATTERN = Pattern.compile("^\\d{4}$"); + private static final Pattern PASSWORD_PATTERN = Pattern.compile(String.format("^\\d{%d}$", PASSWORD_LENGTH)); @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -41,16 +42,16 @@ public Event(String name, String password, String token) { } private void validateName(String name) { - int nameLength = name.length(); + int nameLength = name.trim().length(); if (nameLength < MIN_NAME_LENGTH || MAX_NAME_LENGTH < nameLength) { - throw new HaengdongException(HaengdongErrorCode.BAD_REQUEST, + throw new HaengdongException(HaengdongErrorCode.EVENT_NAME_LENGTH_INVALID, String.format("행사 이름은 %d자 이상 %d자 이하만 입력 가능합니다. 입력한 이름 길이 : %d", MIN_NAME_LENGTH, MAX_NAME_LENGTH, name.length())); } if (isBlankContinuous(name)) { - throw new HaengdongException(HaengdongErrorCode.BAD_REQUEST, + throw new HaengdongException(HaengdongErrorCode.EVENT_NAME_CONSECUTIVE_SPACES, String.format("행사 이름에는 공백 문자가 연속될 수 없습니다. 입력한 이름 : %s", name)); } } @@ -58,7 +59,7 @@ private void validateName(String name) { private void validatePassword(String password) { Matcher matcher = PASSWORD_PATTERN.matcher(password); if (!matcher.matches()) { - throw new HaengdongException(HaengdongErrorCode.BAD_REQUEST, "비밀번호는 4자리 숫자만 가능합니다."); + throw new HaengdongException(HaengdongErrorCode.EVENT_PASSWORD_FORMAT_INVALID, "비밀번호는 4자리 숫자만 가능합니다."); } } diff --git a/server/src/main/java/server/haengdong/exception/AuthenticationException.java b/server/src/main/java/server/haengdong/exception/AuthenticationException.java index 78a16e295..2efcb16e7 100644 --- a/server/src/main/java/server/haengdong/exception/AuthenticationException.java +++ b/server/src/main/java/server/haengdong/exception/AuthenticationException.java @@ -1,4 +1,19 @@ package server.haengdong.exception; +import lombok.Getter; + +@Getter public class AuthenticationException extends RuntimeException { + + private final HaengdongErrorCode errorCode; + private final String message; + + public AuthenticationException(HaengdongErrorCode errorCode) { + this(errorCode, errorCode.getMessage()); + } + + public AuthenticationException(HaengdongErrorCode errorCode, String message) { + this.errorCode = errorCode; + this.message = message; + } } diff --git a/server/src/main/java/server/haengdong/exception/ErrorResponse.java b/server/src/main/java/server/haengdong/exception/ErrorResponse.java index 69133a66c..d0a2b01a0 100644 --- a/server/src/main/java/server/haengdong/exception/ErrorResponse.java +++ b/server/src/main/java/server/haengdong/exception/ErrorResponse.java @@ -1,15 +1,15 @@ package server.haengdong.exception; public record ErrorResponse( - String code, + HaengdongErrorCode errorCode, String message ) { public static ErrorResponse of(HaengdongErrorCode errorCode) { - return new ErrorResponse(errorCode.getCode(), errorCode.getMessage()); + return new ErrorResponse(errorCode, errorCode.getMessage()); } - public static ErrorResponse of(HaengdongErrorCode errorCode, String message){ - return new ErrorResponse(errorCode.getCode(), message); + public static ErrorResponse of(HaengdongErrorCode errorCode, String message) { + return new ErrorResponse(errorCode, message); } } diff --git a/server/src/main/java/server/haengdong/exception/GlobalExceptionHandler.java b/server/src/main/java/server/haengdong/exception/GlobalExceptionHandler.java index e45f2da67..026ee3452 100644 --- a/server/src/main/java/server/haengdong/exception/GlobalExceptionHandler.java +++ b/server/src/main/java/server/haengdong/exception/GlobalExceptionHandler.java @@ -16,9 +16,9 @@ public class GlobalExceptionHandler { @ExceptionHandler(AuthenticationException.class) - public ResponseEntity authenticationException() { + public ResponseEntity authenticationException(AuthenticationException e) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) - .body(ErrorResponse.of(HaengdongErrorCode.UNAUTHORIZED)); + .body(ErrorResponse.of(e.getErrorCode())); } @ExceptionHandler({HttpRequestMethodNotSupportedException.class, NoResourceFoundException.class}) @@ -41,7 +41,7 @@ public ResponseEntity handleMethodArgumentNotValidException(Metho .collect(Collectors.joining(", ")); return ResponseEntity.badRequest() - .body(ErrorResponse.of(HaengdongErrorCode.BAD_REQUEST, errorMessage)); + .body(ErrorResponse.of(HaengdongErrorCode.REQUEST_EMPTY, errorMessage)); } @ExceptionHandler(HaengdongException.class) diff --git a/server/src/main/java/server/haengdong/exception/HaengdongErrorCode.java b/server/src/main/java/server/haengdong/exception/HaengdongErrorCode.java index 93667d052..bd0866d00 100644 --- a/server/src/main/java/server/haengdong/exception/HaengdongErrorCode.java +++ b/server/src/main/java/server/haengdong/exception/HaengdongErrorCode.java @@ -1,29 +1,63 @@ package server.haengdong.exception; import lombok.Getter; +import server.haengdong.domain.action.BillAction; +import server.haengdong.domain.action.MemberAction; +import server.haengdong.domain.event.Event; @Getter public enum HaengdongErrorCode { - BAD_REQUEST("R_001", "잘못된 요청입니다."), - NO_RESOURCE_REQUEST("R_002", "잘못된 엔드포인트입니다."), - MESSAGE_NOT_READABLE("R_003", "읽을 수 없는 요청 형식입니다."), - UNAUTHORIZED("A_001", "인증에 실패했습니다."), - INTERNAL_SERVER_ERROR("S_001", "서버 내부에서 에러가 발생했습니다."), - DUPLICATED_MEMBER_NAME("EV_001", "중복된 행사 참여 인원 이름이 존재합니다."), - NOT_FOUND_EVENT("EV_400", "존재하지 않는 행사입니다."), - DUPLICATED_MEMBER_ACTION("MA_001", "중복된 인원이 존재합니다."), - INVALID_MEMBER_IN_ACTION("MA_002", "현재 참여하고 있는 인원이 존재합니다."), - INVALID_MEMBER_OUT_ACTION("MA_003", "현재 참여하고 있지 않는 인원이 존재합니다."), - NOT_FOUND_MEMBER_ACTION("MA_400", "존재하지 않는 멤버 액션입니다."), - NOT_FOUND_BILL_ACTION("BA_400", "존재하지 않는 지출 액션입니다."), - NOT_FOUND_ACTION("AC_400", "존재하지 않는 액션입니다."), - ; - - private final String code; + + /* Domain */ + + EVENT_NOT_FOUND("존재하지 않는 행사입니다."), + EVENT_NAME_LENGTH_INVALID(String.format("행사 이름은 %d자 이상 %d자 이하만 입력 가능합니다.", + Event.MIN_NAME_LENGTH, + Event.MAX_NAME_LENGTH)), + EVENT_NAME_CONSECUTIVE_SPACES("행사 이름에는 공백 문자가 연속될 수 없습니다. 입력한 이름 : %s"), + EVENT_PASSWORD_FORMAT_INVALID(String.format("비밀번호는 %d자리 숫자만 가능합니다.", Event.PASSWORD_LENGTH)), + + ACTION_NOT_FOUND("존재하지 않는 액션입니다."), + + MEMBER_NAME_LENGTH_INVALID(String.format("멤버 이름은 %d자 이상 %d자 이하만 입력 가능합니다.", + MemberAction.MIN_NAME_LENGTH, + MemberAction.MAX_NAME_LENGTH)), + MEMBER_NAME_DUPLICATE("중복된 행사 참여 인원 이름이 존재합니다."), + MEMBER_NOT_EXIST("현재 참여하고 있지 않는 인원이 존재합니다."), + MEMBER_ALREADY_EXIST("현재 참여하고 있는 인원이 존재합니다."), + + MEMBER_ACTION_NOT_FOUND("존재하지 않는 멤버 액션입니다."), + MEMBER_ACTION_STATUS_INVALID("멤버 액션은 IN, OUT만 가능합니다. 입력한 멤버 액션: %s"), + + BILL_ACTION_NOT_FOUND("존재하지 않는 지출 액션입니다."), + BILL_ACTION_TITLE_INVALID(String.format("앞뒤 공백을 제거한 지출 내역 제목은 %d ~ %d자여야 합니다.", + BillAction.MIN_TITLE_LENGTH, + BillAction.MAX_TITLE_LENGTH)), + BILL_ACTION_PRICE_INVALID(String.format("지출 금액은 %,d 이하의 자연수여야 합니다.", BillAction.MAX_PRICE)), + + /* Authentication */ + + PASSWORD_INVALID("비밀번호가 일치하지 않습니다."), + + TOKEN_NOT_FOUND("토큰이 존재하지 않습니다."), + TOKEN_EXPIRED("만료된 토큰입니다."), + TOKEN_INVALID("유효하지 않은 토큰입니다."), + + FORBIDDEN("접근할 수 없는 행사입니다."), + + /* Request Validation */ + + REQUEST_EMPTY("입력 값은 공백일 수 없습니다.") + + /* System */, + + MESSAGE_NOT_READABLE("읽을 수 없는 요청입니다."), + NO_RESOURCE_REQUEST("존재하지 않는 자원입니다."), + INTERNAL_SERVER_ERROR("서버 내부에서 에러가 발생했습니다."); + private final String message; - HaengdongErrorCode(String code, String message) { - this.code = code; + HaengdongErrorCode(String message) { this.message = message; } } diff --git a/server/src/main/java/server/haengdong/exception/HaengdongException.java b/server/src/main/java/server/haengdong/exception/HaengdongException.java index d418a2feb..b86fe4ffc 100644 --- a/server/src/main/java/server/haengdong/exception/HaengdongException.java +++ b/server/src/main/java/server/haengdong/exception/HaengdongException.java @@ -9,19 +9,11 @@ public class HaengdongException extends RuntimeException { private final String message; public HaengdongException(HaengdongErrorCode errorCode) { - this(errorCode, null); + this(errorCode, errorCode.getMessage()); } public HaengdongException(HaengdongErrorCode errorCode, String message) { this.errorCode = errorCode; this.message = message; } - - @Override - public String getMessage() { - if (message == null) { - return errorCode.getMessage(); - } - return message; - } } diff --git a/server/src/main/java/server/haengdong/infrastructure/auth/AuthenticationExtractor.java b/server/src/main/java/server/haengdong/infrastructure/auth/AuthenticationExtractor.java index 74489577d..4972de48a 100644 --- a/server/src/main/java/server/haengdong/infrastructure/auth/AuthenticationExtractor.java +++ b/server/src/main/java/server/haengdong/infrastructure/auth/AuthenticationExtractor.java @@ -4,19 +4,20 @@ import jakarta.servlet.http.HttpServletRequest; import java.util.Arrays; import server.haengdong.exception.AuthenticationException; +import server.haengdong.exception.HaengdongErrorCode; public class AuthenticationExtractor { public String extract(HttpServletRequest request, String cookieName) { Cookie[] cookies = request.getCookies(); if (cookies == null) { - throw new AuthenticationException(); + throw new AuthenticationException(HaengdongErrorCode.TOKEN_NOT_FOUND); } return Arrays.stream(cookies) .filter(cookie -> cookieName.equals(cookie.getName())) .findFirst() - .orElseThrow(AuthenticationException::new) + .orElseThrow(() -> new AuthenticationException(HaengdongErrorCode.TOKEN_NOT_FOUND)) .getValue(); } } diff --git a/server/src/main/java/server/haengdong/presentation/request/BillActionSaveRequest.java b/server/src/main/java/server/haengdong/presentation/request/BillActionSaveRequest.java index a0d878f7f..a47ff8316 100644 --- a/server/src/main/java/server/haengdong/presentation/request/BillActionSaveRequest.java +++ b/server/src/main/java/server/haengdong/presentation/request/BillActionSaveRequest.java @@ -6,10 +6,10 @@ public record BillActionSaveRequest( - @NotBlank + @NotBlank(message = "지출 내역 제목은 공백일 수 없습니다.") String title, - @NotNull + @NotNull(message = "지출 금액은 공백일 수 없습니다.") Long price ) { diff --git a/server/src/main/java/server/haengdong/presentation/request/BillActionUpdateRequest.java b/server/src/main/java/server/haengdong/presentation/request/BillActionUpdateRequest.java index 6f1a0a734..680006816 100644 --- a/server/src/main/java/server/haengdong/presentation/request/BillActionUpdateRequest.java +++ b/server/src/main/java/server/haengdong/presentation/request/BillActionUpdateRequest.java @@ -6,13 +6,13 @@ public record BillActionUpdateRequest( - @NotBlank + @NotBlank(message = "지출 내역 제목은 공백일 수 없습니다.") String title, - @NotNull + @NotNull(message = "지출 금액은 공백일 수 없습니다.") Long price ) { - public BillActionUpdateAppRequest toAppResponse() { - return new BillActionUpdateAppRequest(title, price); - } + public BillActionUpdateAppRequest toAppResponse() { + return new BillActionUpdateAppRequest(title, price); + } } diff --git a/server/src/main/java/server/haengdong/presentation/request/BillActionsSaveRequest.java b/server/src/main/java/server/haengdong/presentation/request/BillActionsSaveRequest.java index 68784039b..42bf86149 100644 --- a/server/src/main/java/server/haengdong/presentation/request/BillActionsSaveRequest.java +++ b/server/src/main/java/server/haengdong/presentation/request/BillActionsSaveRequest.java @@ -4,7 +4,10 @@ import java.util.List; import server.haengdong.application.request.BillActionAppRequest; -public record BillActionsSaveRequest(@Valid List actions) { +public record BillActionsSaveRequest( + + @Valid List actions +) { public List toAppRequests() { return actions.stream() diff --git a/server/src/main/java/server/haengdong/presentation/request/EventLoginRequest.java b/server/src/main/java/server/haengdong/presentation/request/EventLoginRequest.java index d1e743821..a1286e903 100644 --- a/server/src/main/java/server/haengdong/presentation/request/EventLoginRequest.java +++ b/server/src/main/java/server/haengdong/presentation/request/EventLoginRequest.java @@ -5,10 +5,10 @@ public record EventLoginRequest( - @NotBlank + @NotBlank(message = "비밀번호는 공백일 수 없습니다.") String password ) { - public EventLoginAppRequest toAppRequest(String token) { - return new EventLoginAppRequest(token, password); - } + public EventLoginAppRequest toAppRequest(String token) { + return new EventLoginAppRequest(token, password); + } } diff --git a/server/src/main/java/server/haengdong/presentation/request/EventSaveRequest.java b/server/src/main/java/server/haengdong/presentation/request/EventSaveRequest.java index fb9683916..6bd7cd006 100644 --- a/server/src/main/java/server/haengdong/presentation/request/EventSaveRequest.java +++ b/server/src/main/java/server/haengdong/presentation/request/EventSaveRequest.java @@ -5,10 +5,10 @@ public record EventSaveRequest( - @NotBlank + @NotBlank(message = "행사 이름은 공백일 수 없습니다.") String eventName, - @NotBlank + @NotBlank(message = "비밀번호는 공백일 수 없습니다.") String password ) { diff --git a/server/src/main/java/server/haengdong/presentation/request/MemberActionsSaveRequest.java b/server/src/main/java/server/haengdong/presentation/request/MemberActionsSaveRequest.java index 0b3fcebae..828fc7b4c 100644 --- a/server/src/main/java/server/haengdong/presentation/request/MemberActionsSaveRequest.java +++ b/server/src/main/java/server/haengdong/presentation/request/MemberActionsSaveRequest.java @@ -8,7 +8,7 @@ public record MemberActionsSaveRequest( List members, - @NotBlank + @NotBlank(message = "멤버 액션은 공백일 수 없습니다.") String status ) { diff --git a/server/src/main/java/server/haengdong/presentation/request/MemberUpdateRequest.java b/server/src/main/java/server/haengdong/presentation/request/MemberUpdateRequest.java index 71f0b4ec7..412457750 100644 --- a/server/src/main/java/server/haengdong/presentation/request/MemberUpdateRequest.java +++ b/server/src/main/java/server/haengdong/presentation/request/MemberUpdateRequest.java @@ -4,7 +4,9 @@ import server.haengdong.application.request.MemberUpdateAppRequest; public record MemberUpdateRequest( - @NotBlank String name + + @NotBlank(message = "멤버 이름은 공백일 수 없습니다.") + String name ) { public MemberUpdateAppRequest toAppRequest() { diff --git a/server/src/test/java/server/haengdong/application/ActionServiceTest.java b/server/src/test/java/server/haengdong/application/ActionServiceTest.java index ad6c60aa9..05a622d34 100644 --- a/server/src/test/java/server/haengdong/application/ActionServiceTest.java +++ b/server/src/test/java/server/haengdong/application/ActionServiceTest.java @@ -72,6 +72,6 @@ void getMemberBillReports() { void getMemberBillReports1() { assertThatThrownBy(() -> actionService.getMemberBillReports("invalid token")) .isInstanceOf(HaengdongException.class) - .hasMessage(HaengdongErrorCode.NOT_FOUND_EVENT.getMessage()); + .hasMessage(HaengdongErrorCode.EVENT_NOT_FOUND.getMessage()); } } diff --git a/server/src/test/java/server/haengdong/domain/action/BillActionTest.java b/server/src/test/java/server/haengdong/domain/action/BillActionTest.java index 851ed14d9..13e4bca68 100644 --- a/server/src/test/java/server/haengdong/domain/action/BillActionTest.java +++ b/server/src/test/java/server/haengdong/domain/action/BillActionTest.java @@ -14,9 +14,9 @@ class BillActionTest { - @DisplayName("지출 내역 제목의 앞뒤 공백을 제거한 길이가 2 ~ 30자가 아니면 지출을 생성할 수 없다.") + @DisplayName("지출 내역 제목의 앞뒤 공백을 제거한 길이가 1 ~ 30자가 아니면 지출을 생성할 수 없다.") @ParameterizedTest - @ValueSource(strings = {" 감 ", "", " ", "1234567890123456789012345678901"}) + @ValueSource(strings = {"", " ", "1234567890123456789012345678901"}) void validateTitle(String title) { Event event = Fixture.EVENT1; Action action = new Action(event, 1L); @@ -24,7 +24,7 @@ void validateTitle(String title) { assertThatThrownBy(() -> new BillAction(action, title, price)) .isInstanceOf(HaengdongException.class) - .hasMessage("앞뒤 공백을 제거한 지출 내역 제목은 2 ~ 30자여야 합니다."); + .hasMessage("앞뒤 공백을 제거한 지출 내역 제목은 1 ~ 30자여야 합니다."); } @DisplayName("금액이 10,000,000 이하의 자연수가 아니면 지출을 생성할 수 없다.") diff --git a/server/src/test/java/server/haengdong/domain/event/EventTest.java b/server/src/test/java/server/haengdong/domain/event/EventTest.java index 0d5b58519..a7dba49d9 100644 --- a/server/src/test/java/server/haengdong/domain/event/EventTest.java +++ b/server/src/test/java/server/haengdong/domain/event/EventTest.java @@ -26,13 +26,13 @@ void createFailTest1(String eventName) { .hasMessage(String.format("행사 이름에는 공백 문자가 연속될 수 없습니다. 입력한 이름 : %s", eventName)); } - @DisplayName("이름이 2자 미만이거나 20자 초과인 경우 예외가 발생한다.") + @DisplayName("이름이 1자 미만이거나 20자 초과인 경우 예외가 발생한다.") @ParameterizedTest @ValueSource(strings = {"", " ", "123456789012345678901"}) void createFilTest2(String eventName) { assertThatCode(() -> new Event(eventName, "1234", "TEST_TOKEN")) .isInstanceOf(HaengdongException.class) - .hasMessage(String.format("행사 이름은 2자 이상 20자 이하만 입력 가능합니다. 입력한 이름 길이 : %d", eventName.length())); + .hasMessage(String.format("행사 이름은 1자 이상 20자 이하만 입력 가능합니다. 입력한 이름 길이 : %d", eventName.length())); } @DisplayName("비밀번호는 4자리 숫자 입니다.") diff --git a/server/src/test/java/server/haengdong/presentation/BillActionControllerTest.java b/server/src/test/java/server/haengdong/presentation/BillActionControllerTest.java index 1c3984e7c..4420e369c 100644 --- a/server/src/test/java/server/haengdong/presentation/BillActionControllerTest.java +++ b/server/src/test/java/server/haengdong/presentation/BillActionControllerTest.java @@ -87,7 +87,7 @@ void deleteBillAction() throws Exception { @Test void deleteBillAction1() throws Exception { String eventId = "이상해토큰"; - doThrow(new HaengdongException(HaengdongErrorCode.NOT_FOUND_EVENT)) + doThrow(new HaengdongException(HaengdongErrorCode.EVENT_NOT_FOUND)) .when(billActionService).deleteBillAction(any(String.class), any(Long.class)); mockMvc.perform(delete("/api/events/{eventId}/bill-actions/{actionId}", eventId, 1))