From dbbb8afd8e8d560abd549346e4c4f802b6716c5a Mon Sep 17 00:00:00 2001 From: mandykr Date: Tue, 25 Feb 2025 14:40:52 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=EB=B9=84=EC=A6=88=EB=8B=88?= =?UTF-8?q?=EC=8A=A4=20=EC=98=88=EC=99=B8=EC=99=80=20API=20=EA=B3=B5?= =?UTF-8?q?=ED=86=B5=20=EC=9D=91=EB=8B=B5=20=EB=AA=A8=EB=93=88=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20-=20vo=20=EA=B2=80=EC=A6=9D=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=ED=95=98=EB=8A=94=20=EB=B9=84=EC=A6=88?= =?UTF-8?q?=EB=8B=88=EC=8A=A4=20=EC=98=88=EC=99=B8=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EB=B0=8F=20InvalidValueException=20=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crew/domain/entity/Announcement.java | 1 - .../AnnouncementContentException.java | 8 --- .../exception/AnnouncementTitleException.java | 8 --- .../exception/CrewDescriptionException.java | 8 --- .../crew/domain/exception/CrewErrorCode.java | 17 ------ .../crew/domain/exception/CrewException.java | 10 ---- .../exception/CrewNotFoundException.java | 12 +++++ .../domain/exception/CrewTitleException.java | 7 --- .../IntroductionContentException.java | 9 ---- .../exception/IntroductionTitleException.java | 9 ---- .../exception/PostContentException.java | 8 --- .../domain/exception/PostTitleException.java | 8 --- .../exception/common/BusinessException.java | 24 +++++++++ .../common/EntityNotFoundException.java | 16 ++++++ .../domain/exception/common/ErrorCode.java | 27 ++++++++++ .../common/InvalidValueException.java | 17 ++++++ .../crew/domain/vo/AnnouncementContent.java | 4 +- .../crew/domain/vo/AnnouncementTitle.java | 4 +- .../crew/domain/vo/CrewDescription.java | 4 +- .../com/retrip/crew/domain/vo/CrewTitle.java | 4 +- .../crew/domain/vo/IntroductionContent.java | 4 +- .../crew/domain/vo/IntroductionTitle.java | 5 +- .../domain/vo/NotificationBoardContent.java | 38 ------------- .../retrip/crew/domain/vo/PostContent.java | 4 +- .../com/retrip/crew/domain/vo/PostTitle.java | 4 +- .../in/presentation/rest/CrewController.java | 33 ++++++++++-- .../presentation/rest/common/ApiResponse.java | 37 +++++++++++++ .../rest/common/ErrorResponse.java | 37 +++++++++++++ .../rest/common/GlobalExceptionHandler.java | 54 +++++++++++++++++++ .../domain/vo/CrewIntroductionTitleTest.java | 5 +- 30 files changed, 272 insertions(+), 154 deletions(-) delete mode 100644 src/main/java/com/retrip/crew/domain/exception/AnnouncementContentException.java delete mode 100644 src/main/java/com/retrip/crew/domain/exception/AnnouncementTitleException.java delete mode 100644 src/main/java/com/retrip/crew/domain/exception/CrewDescriptionException.java delete mode 100644 src/main/java/com/retrip/crew/domain/exception/CrewErrorCode.java delete mode 100644 src/main/java/com/retrip/crew/domain/exception/CrewException.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/CrewNotFoundException.java delete mode 100644 src/main/java/com/retrip/crew/domain/exception/CrewTitleException.java delete mode 100644 src/main/java/com/retrip/crew/domain/exception/IntroductionContentException.java delete mode 100644 src/main/java/com/retrip/crew/domain/exception/IntroductionTitleException.java delete mode 100644 src/main/java/com/retrip/crew/domain/exception/PostContentException.java delete mode 100644 src/main/java/com/retrip/crew/domain/exception/PostTitleException.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/common/BusinessException.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/common/EntityNotFoundException.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/common/ErrorCode.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/common/InvalidValueException.java delete mode 100644 src/main/java/com/retrip/crew/domain/vo/NotificationBoardContent.java create mode 100644 src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/common/ApiResponse.java create mode 100644 src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/common/ErrorResponse.java create mode 100644 src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/common/GlobalExceptionHandler.java diff --git a/src/main/java/com/retrip/crew/domain/entity/Announcement.java b/src/main/java/com/retrip/crew/domain/entity/Announcement.java index ca4def9..694a274 100644 --- a/src/main/java/com/retrip/crew/domain/entity/Announcement.java +++ b/src/main/java/com/retrip/crew/domain/entity/Announcement.java @@ -2,7 +2,6 @@ import com.retrip.crew.domain.vo.AnnouncementContent; import com.retrip.crew.domain.vo.AnnouncementTitle; -import com.retrip.crew.domain.vo.NotificationBoardContent; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; diff --git a/src/main/java/com/retrip/crew/domain/exception/AnnouncementContentException.java b/src/main/java/com/retrip/crew/domain/exception/AnnouncementContentException.java deleted file mode 100644 index 554d584..0000000 --- a/src/main/java/com/retrip/crew/domain/exception/AnnouncementContentException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.retrip.crew.domain.exception; - -public class AnnouncementContentException extends CrewException { - - public AnnouncementContentException(String message) { - super(CrewErrorCode.ANNOUNCEMENT_CONTENT_ERROR, message); - } -} diff --git a/src/main/java/com/retrip/crew/domain/exception/AnnouncementTitleException.java b/src/main/java/com/retrip/crew/domain/exception/AnnouncementTitleException.java deleted file mode 100644 index 571ae90..0000000 --- a/src/main/java/com/retrip/crew/domain/exception/AnnouncementTitleException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.retrip.crew.domain.exception; - -public class AnnouncementTitleException extends CrewException { - - public AnnouncementTitleException(String message) { - super(CrewErrorCode.ANNOUNCEMENT_TITLE_ERROR, message); - } -} diff --git a/src/main/java/com/retrip/crew/domain/exception/CrewDescriptionException.java b/src/main/java/com/retrip/crew/domain/exception/CrewDescriptionException.java deleted file mode 100644 index 04db44e..0000000 --- a/src/main/java/com/retrip/crew/domain/exception/CrewDescriptionException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.retrip.crew.domain.exception; - -public class CrewDescriptionException extends CrewException { - - public CrewDescriptionException(String message) { - super(CrewErrorCode.CREW_DESCRIPTION_ERROR, message); - } -} diff --git a/src/main/java/com/retrip/crew/domain/exception/CrewErrorCode.java b/src/main/java/com/retrip/crew/domain/exception/CrewErrorCode.java deleted file mode 100644 index d494b90..0000000 --- a/src/main/java/com/retrip/crew/domain/exception/CrewErrorCode.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.retrip.crew.domain.exception; - -public enum CrewErrorCode { - CREW_TITLE_ERROR(1001), - CREW_DESCRIPTION_ERROR(1002), - POST_TITLE_ERROR(1003), - POST_CONTENT_ERROR(1004), - ANNOUNCEMENT_TITLE_ERROR(1005), - ANNOUNCEMENT_CONTENT_ERROR(1006), - INTRODUCTION_TITLE_ERROR(1007), - INTRODUCTION_CONTENT_ERROR(1008); - - private final int code; - CrewErrorCode(int code) { - this.code = code; - } -} diff --git a/src/main/java/com/retrip/crew/domain/exception/CrewException.java b/src/main/java/com/retrip/crew/domain/exception/CrewException.java deleted file mode 100644 index 6b851e9..0000000 --- a/src/main/java/com/retrip/crew/domain/exception/CrewException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.retrip.crew.domain.exception; - -public abstract class CrewException extends RuntimeException { - private final CrewErrorCode errorCode; - - public CrewException(CrewErrorCode errorCode, String message) { - super(message); - this.errorCode = errorCode; - } -} diff --git a/src/main/java/com/retrip/crew/domain/exception/CrewNotFoundException.java b/src/main/java/com/retrip/crew/domain/exception/CrewNotFoundException.java new file mode 100644 index 0000000..868e539 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/CrewNotFoundException.java @@ -0,0 +1,12 @@ +package com.retrip.crew.domain.exception; + +import com.retrip.crew.domain.exception.common.EntityNotFoundException; +import com.retrip.crew.domain.exception.common.ErrorCode; + +public class CrewNotFoundException extends EntityNotFoundException { + private static final ErrorCode errorCode = ErrorCode.CREW_NOT_FOUNT; + + public CrewNotFoundException() { + super(errorCode); + } +} diff --git a/src/main/java/com/retrip/crew/domain/exception/CrewTitleException.java b/src/main/java/com/retrip/crew/domain/exception/CrewTitleException.java deleted file mode 100644 index ae1c0c1..0000000 --- a/src/main/java/com/retrip/crew/domain/exception/CrewTitleException.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.retrip.crew.domain.exception; - -public class CrewTitleException extends CrewException { - public CrewTitleException(String message) { - super(CrewErrorCode.CREW_TITLE_ERROR, message); - } -} diff --git a/src/main/java/com/retrip/crew/domain/exception/IntroductionContentException.java b/src/main/java/com/retrip/crew/domain/exception/IntroductionContentException.java deleted file mode 100644 index ab07f4b..0000000 --- a/src/main/java/com/retrip/crew/domain/exception/IntroductionContentException.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.retrip.crew.domain.exception; - -public class IntroductionContentException extends CrewException { - private static final int ERROR_CODE = 1003; - - public IntroductionContentException(String message) { - super(CrewErrorCode.INTRODUCTION_CONTENT_ERROR, message); - } -} diff --git a/src/main/java/com/retrip/crew/domain/exception/IntroductionTitleException.java b/src/main/java/com/retrip/crew/domain/exception/IntroductionTitleException.java deleted file mode 100644 index 6d7af3e..0000000 --- a/src/main/java/com/retrip/crew/domain/exception/IntroductionTitleException.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.retrip.crew.domain.exception; - -public class IntroductionTitleException extends CrewException { - private static final int ERROR_CODE = 1003; - - public IntroductionTitleException(String message) { - super(CrewErrorCode.INTRODUCTION_TITLE_ERROR, message); - } -} diff --git a/src/main/java/com/retrip/crew/domain/exception/PostContentException.java b/src/main/java/com/retrip/crew/domain/exception/PostContentException.java deleted file mode 100644 index 997f665..0000000 --- a/src/main/java/com/retrip/crew/domain/exception/PostContentException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.retrip.crew.domain.exception; - -public class PostContentException extends CrewException { - - public PostContentException(String message) { - super(CrewErrorCode.POST_CONTENT_ERROR, message); - } -} diff --git a/src/main/java/com/retrip/crew/domain/exception/PostTitleException.java b/src/main/java/com/retrip/crew/domain/exception/PostTitleException.java deleted file mode 100644 index 64afe6c..0000000 --- a/src/main/java/com/retrip/crew/domain/exception/PostTitleException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.retrip.crew.domain.exception; - -public class PostTitleException extends CrewException { - - public PostTitleException(String message) { - super(CrewErrorCode.POST_TITLE_ERROR, message); - } -} diff --git a/src/main/java/com/retrip/crew/domain/exception/common/BusinessException.java b/src/main/java/com/retrip/crew/domain/exception/common/BusinessException.java new file mode 100644 index 0000000..db24543 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/common/BusinessException.java @@ -0,0 +1,24 @@ +package com.retrip.crew.domain.exception.common; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +public class BusinessException extends RuntimeException { + private final ErrorCode errorCode; + + public BusinessException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode = errorCode; + } + + public BusinessException(String message, ErrorCode errorCode) { + super(message); + this.errorCode = errorCode; + } + + public BusinessException(ErrorCode errorCode, String message) { + super(message); + this.errorCode = errorCode; + } +} diff --git a/src/main/java/com/retrip/crew/domain/exception/common/EntityNotFoundException.java b/src/main/java/com/retrip/crew/domain/exception/common/EntityNotFoundException.java new file mode 100644 index 0000000..33fc6ca --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/common/EntityNotFoundException.java @@ -0,0 +1,16 @@ +package com.retrip.crew.domain.exception.common; + +public class EntityNotFoundException extends BusinessException { + private static final ErrorCode errorCode = ErrorCode.ENTITY_NOT_FOUNT; + public EntityNotFoundException(ErrorCode errorCode) { + super(errorCode); + } + + public EntityNotFoundException(String message) { + super(errorCode, message); + } + + public EntityNotFoundException(ErrorCode errorCode, String message) { + super(errorCode, message); + } +} diff --git a/src/main/java/com/retrip/crew/domain/exception/common/ErrorCode.java b/src/main/java/com/retrip/crew/domain/exception/common/ErrorCode.java new file mode 100644 index 0000000..dda6974 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/common/ErrorCode.java @@ -0,0 +1,27 @@ +package com.retrip.crew.domain.exception.common; + +import lombok.Getter; +import org.springframework.http.HttpStatus; + +import static org.springframework.http.HttpStatus.*; + +@Getter +public enum ErrorCode { + SERVER_ERROR(INTERNAL_SERVER_ERROR, "Common-001", "Server error"), + INVALID_INPUT_VALUE(BAD_REQUEST, "Common-002", "Invalid input value"), + HANDLE_ACCESS_DENIED(FORBIDDEN, "Common-003", "Access is denied"), + ENTITY_NOT_FOUNT(BAD_REQUEST, "Common-004", "Entity not found"), + + CREW_NOT_FOUNT(BAD_REQUEST, "Crew-001", "크루 엔티티를 찾을 수 없습니다.") + ; + + private final HttpStatus status; + private final String code; + private final String message; + + ErrorCode(HttpStatus status, String code, String message) { + this.status = status; + this.code = code; + this.message = message; + } +} diff --git a/src/main/java/com/retrip/crew/domain/exception/common/InvalidValueException.java b/src/main/java/com/retrip/crew/domain/exception/common/InvalidValueException.java new file mode 100644 index 0000000..546de82 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/common/InvalidValueException.java @@ -0,0 +1,17 @@ +package com.retrip.crew.domain.exception.common; + +public class InvalidValueException extends BusinessException { + private static final ErrorCode errorCode = ErrorCode.INVALID_INPUT_VALUE; + public InvalidValueException(ErrorCode errorCode) { + super(errorCode); + } + + public InvalidValueException(String message) { + super(errorCode, message); + } + + public InvalidValueException(ErrorCode errorCode, String message) { + super(errorCode, message); + } + +} diff --git a/src/main/java/com/retrip/crew/domain/vo/AnnouncementContent.java b/src/main/java/com/retrip/crew/domain/vo/AnnouncementContent.java index e213e0d..5d67c0f 100644 --- a/src/main/java/com/retrip/crew/domain/vo/AnnouncementContent.java +++ b/src/main/java/com/retrip/crew/domain/vo/AnnouncementContent.java @@ -1,6 +1,6 @@ package com.retrip.crew.domain.vo; -import com.retrip.crew.domain.exception.CrewDescriptionException; +import com.retrip.crew.domain.exception.common.InvalidValueException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -25,7 +25,7 @@ public AnnouncementContent(String value) { private void validate(String value) { if (value.length() > CONTENT_LENGTH_LIMIT) { - throw new CrewDescriptionException("공지 게시글 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + throw new InvalidValueException("공지 게시글 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); } } } diff --git a/src/main/java/com/retrip/crew/domain/vo/AnnouncementTitle.java b/src/main/java/com/retrip/crew/domain/vo/AnnouncementTitle.java index 7aabaf1..db5aa3e 100644 --- a/src/main/java/com/retrip/crew/domain/vo/AnnouncementTitle.java +++ b/src/main/java/com/retrip/crew/domain/vo/AnnouncementTitle.java @@ -1,6 +1,6 @@ package com.retrip.crew.domain.vo; -import com.retrip.crew.domain.exception.IntroductionTitleException; +import com.retrip.crew.domain.exception.common.InvalidValueException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -25,7 +25,7 @@ public AnnouncementTitle(String value) { private void validate(String value) { if (value.length() > TITLE_LENGTH_LIMIT) { - throw new IntroductionTitleException("공지 게시글 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + throw new InvalidValueException("공지 게시글 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); } } } diff --git a/src/main/java/com/retrip/crew/domain/vo/CrewDescription.java b/src/main/java/com/retrip/crew/domain/vo/CrewDescription.java index 76c0eb9..e6789b5 100644 --- a/src/main/java/com/retrip/crew/domain/vo/CrewDescription.java +++ b/src/main/java/com/retrip/crew/domain/vo/CrewDescription.java @@ -1,6 +1,6 @@ package com.retrip.crew.domain.vo; -import com.retrip.crew.domain.exception.CrewDescriptionException; +import com.retrip.crew.domain.exception.common.InvalidValueException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -25,7 +25,7 @@ public CrewDescription(String value) { private void validate(String value) { if (value.length() > DESCRIPTION_LENGTH_LIMIT) { - throw new CrewDescriptionException("크루 상세 설명은 " + DESCRIPTION_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + throw new InvalidValueException("크루 상세 설명은 " + DESCRIPTION_LENGTH_LIMIT + "자를 넘을 수 없습니다."); } } } diff --git a/src/main/java/com/retrip/crew/domain/vo/CrewTitle.java b/src/main/java/com/retrip/crew/domain/vo/CrewTitle.java index 50cdbac..149ff6d 100644 --- a/src/main/java/com/retrip/crew/domain/vo/CrewTitle.java +++ b/src/main/java/com/retrip/crew/domain/vo/CrewTitle.java @@ -1,6 +1,6 @@ package com.retrip.crew.domain.vo; -import com.retrip.crew.domain.exception.CrewTitleException; +import com.retrip.crew.domain.exception.common.InvalidValueException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -25,7 +25,7 @@ public CrewTitle(String value) { private void validate(String value) { if (value.length() > TITLE_LENGTH_LIMIT) { - throw new CrewTitleException("크루 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + throw new InvalidValueException("크루 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); } } } diff --git a/src/main/java/com/retrip/crew/domain/vo/IntroductionContent.java b/src/main/java/com/retrip/crew/domain/vo/IntroductionContent.java index 6001175..0ffd8b3 100644 --- a/src/main/java/com/retrip/crew/domain/vo/IntroductionContent.java +++ b/src/main/java/com/retrip/crew/domain/vo/IntroductionContent.java @@ -1,6 +1,6 @@ package com.retrip.crew.domain.vo; -import com.retrip.crew.domain.exception.CrewDescriptionException; +import com.retrip.crew.domain.exception.common.InvalidValueException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -25,7 +25,7 @@ public IntroductionContent(String value) { private void validate(String value) { if (value.length() > CONTENT_LENGTH_LIMIT) { - throw new CrewDescriptionException("자기 소개 게시글 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + throw new InvalidValueException("자기 소개 게시글 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); } } } diff --git a/src/main/java/com/retrip/crew/domain/vo/IntroductionTitle.java b/src/main/java/com/retrip/crew/domain/vo/IntroductionTitle.java index 7668e76..5b06b18 100644 --- a/src/main/java/com/retrip/crew/domain/vo/IntroductionTitle.java +++ b/src/main/java/com/retrip/crew/domain/vo/IntroductionTitle.java @@ -1,7 +1,6 @@ package com.retrip.crew.domain.vo; -import com.retrip.crew.domain.exception.CrewTitleException; -import com.retrip.crew.domain.exception.IntroductionTitleException; +import com.retrip.crew.domain.exception.common.InvalidValueException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -26,7 +25,7 @@ public IntroductionTitle(String value) { private void validate(String value) { if (value.length() > TITLE_LENGTH_LIMIT) { - throw new IntroductionTitleException("자기 소개 게시글 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + throw new InvalidValueException("자기 소개 게시글 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); } } } diff --git a/src/main/java/com/retrip/crew/domain/vo/NotificationBoardContent.java b/src/main/java/com/retrip/crew/domain/vo/NotificationBoardContent.java deleted file mode 100644 index eeb7017..0000000 --- a/src/main/java/com/retrip/crew/domain/vo/NotificationBoardContent.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.retrip.crew.domain.vo; - -import jakarta.persistence.Column; -import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@Embeddable -@EqualsAndHashCode -@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) -public class NotificationBoardContent { - private static final int TITLE_LENGTH_LIMIT = 30; - private static final int CONTENT_LENGTH_LIMIT = 100; - - @Column(name = "title", nullable = false, length = TITLE_LENGTH_LIMIT) - private final String title; - - @Column(name = "content", nullable = false, length = CONTENT_LENGTH_LIMIT) - private final String content; - - public NotificationBoardContent(String title, String content) { - validate(title, content); - this.title = title; - this.content = content; - } - - private void validate(String title, String content) { - if (title.length() > TITLE_LENGTH_LIMIT) { - throw new IllegalArgumentException("공지 게시글 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); - } - if (content.length() > CONTENT_LENGTH_LIMIT) { - throw new IllegalArgumentException("공지 게시글 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); - } - } -} diff --git a/src/main/java/com/retrip/crew/domain/vo/PostContent.java b/src/main/java/com/retrip/crew/domain/vo/PostContent.java index 65dcb15..bc57e38 100644 --- a/src/main/java/com/retrip/crew/domain/vo/PostContent.java +++ b/src/main/java/com/retrip/crew/domain/vo/PostContent.java @@ -1,6 +1,6 @@ package com.retrip.crew.domain.vo; -import com.retrip.crew.domain.exception.CrewDescriptionException; +import com.retrip.crew.domain.exception.common.InvalidValueException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -25,7 +25,7 @@ public PostContent(String value) { private void validate(String value) { if (value.length() > CONTENT_LENGTH_LIMIT) { - throw new CrewDescriptionException("자유 게시판 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + throw new InvalidValueException("자유 게시판 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); } } } diff --git a/src/main/java/com/retrip/crew/domain/vo/PostTitle.java b/src/main/java/com/retrip/crew/domain/vo/PostTitle.java index 5d2f757..7c9d4f6 100644 --- a/src/main/java/com/retrip/crew/domain/vo/PostTitle.java +++ b/src/main/java/com/retrip/crew/domain/vo/PostTitle.java @@ -1,6 +1,6 @@ package com.retrip.crew.domain.vo; -import com.retrip.crew.domain.exception.IntroductionTitleException; +import com.retrip.crew.domain.exception.common.InvalidValueException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -25,7 +25,7 @@ public PostTitle(String value) { private void validate(String value) { if (value.length() > TITLE_LENGTH_LIMIT) { - throw new IntroductionTitleException("자유 게시판 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + throw new InvalidValueException("자유 게시판 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); } } } diff --git a/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/CrewController.java b/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/CrewController.java index 30171a9..99b4578 100644 --- a/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/CrewController.java +++ b/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/CrewController.java @@ -3,12 +3,17 @@ import com.retrip.crew.application.in.request.CrewCreateRequest; import com.retrip.crew.application.in.response.CrewCreateResponse; import com.retrip.crew.application.in.usecase.CreateCrewUseCase; +import com.retrip.crew.domain.exception.CrewNotFoundException; +import com.retrip.crew.domain.exception.common.ErrorCode; +import com.retrip.crew.domain.exception.common.InvalidValueException; +import com.retrip.crew.infra.adapter.in.presentation.rest.common.ApiResponse; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.net.URI; @@ -23,4 +28,24 @@ public ResponseEntity createCrew(@RequestBody CrewCreateRequ CrewCreateResponse crew = createCrewUseCase.createCrew(request); return ResponseEntity.created(URI.create("/crews/" + crew.id())).body(crew); } + + @PostMapping("/exception1") + public ApiResponse exception1(@RequestBody @Valid CrewCreateRequest request) { + throw new CrewNotFoundException(); + } + + @PostMapping("/exception2") + public ApiResponse exception2(@RequestBody @Valid CrewCreateRequest request) { + throw new InvalidValueException(ErrorCode.SERVER_ERROR); + } + + @PostMapping("/exception3") + public ApiResponse exception3(@RequestBody @Valid CrewCreateRequest request) { + throw new InvalidValueException("인풋 에러"); + } + + @PostMapping("/exception4") + public ApiResponse exception4(@RequestBody @Valid CrewCreateRequest request) { + throw new InvalidValueException(ErrorCode.SERVER_ERROR, "서버 에러"); + } } diff --git a/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/common/ApiResponse.java b/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/common/ApiResponse.java new file mode 100644 index 0000000..b35985d --- /dev/null +++ b/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/common/ApiResponse.java @@ -0,0 +1,37 @@ +package com.retrip.crew.infra.adapter.in.presentation.rest.common; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +import static org.springframework.http.HttpStatus.*; + +@Getter +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class ApiResponse { + private boolean success; + private int status; + private String message; + private T data; + + public static ApiResponse created(T data) { + return success(data, CREATED); + } + + public static ApiResponse ok(T data) { + return success(data, OK); + } + + public static ApiResponse of(T data, HttpStatus status) { + return success(data, status); + } + + private static ApiResponse success(T data, HttpStatus status) { + return new ApiResponse<>(true, status.value(), status.getReasonPhrase(), data); + } + + public static ApiResponse of(ErrorResponse errorResponse) { + return new ApiResponse<>(false, errorResponse.getStatus(), valueOf(errorResponse.getStatus()).getReasonPhrase(), errorResponse); + } +} diff --git a/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/common/ErrorResponse.java b/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/common/ErrorResponse.java new file mode 100644 index 0000000..d602a22 --- /dev/null +++ b/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/common/ErrorResponse.java @@ -0,0 +1,37 @@ +package com.retrip.crew.infra.adapter.in.presentation.rest.common; + +import com.retrip.crew.domain.exception.common.ErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@AllArgsConstructor +public class ErrorResponse { + private int status; + private String code; + private String message; + private String url = "Not available"; + private String method; + private List errors = new ArrayList<>(); + + private ErrorResponse(int status, String code, String message, String url, String method) { + this.status = status; + this.code = code; + this.message = message; + this.url = url; + this.method = method; + } + + public static ErrorResponse of(ErrorCode code, String url, String method, BindingResult bindingResult) { + return new ErrorResponse(code.getStatus().value(), code.getCode(), code.getMessage(), url, method, bindingResult.getFieldErrors()); + } + + public static ErrorResponse of(ErrorCode code, String url, String method) { + return new ErrorResponse(code.getStatus().value(), code.getCode(), code.getMessage(), url, method); + } +} diff --git a/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/common/GlobalExceptionHandler.java b/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/common/GlobalExceptionHandler.java new file mode 100644 index 0000000..bbd83cd --- /dev/null +++ b/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/common/GlobalExceptionHandler.java @@ -0,0 +1,54 @@ +package com.retrip.crew.infra.adapter.in.presentation.rest.common; + +import com.retrip.crew.domain.exception.common.BusinessException; +import com.retrip.crew.domain.exception.common.ErrorCode; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.BindException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.nio.file.AccessDeniedException; + +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(AccessDeniedException.class) + public ApiResponse handleAccessDeniedException(HttpServletRequest request, AccessDeniedException e) { + log.error("handleAccessDeniedException: ", e); + return handle(ErrorCode.HANDLE_ACCESS_DENIED, request); + } + + @ExceptionHandler(BindException.class) + public ApiResponse handleBindException(HttpServletRequest request, BindException e) { + log.error("handleBindException: ", e); + return ApiResponse.of( + ErrorResponse.of( + ErrorCode.INVALID_INPUT_VALUE, + request.getRequestURL().toString(), + request.getMethod(), + e.getBindingResult() + )); + } + + @ExceptionHandler(BusinessException.class) + public ApiResponse handleBusinessException(HttpServletRequest request, BusinessException e) { + log.error("handleBusinessException: ", e); + return handle(e.getErrorCode(), request); + } + + + @ExceptionHandler(Exception.class) + public ApiResponse handleException(HttpServletRequest request, Exception e) { + log.error("handleException: ", e); + return handle(ErrorCode.SERVER_ERROR, request); + } + + private static ApiResponse handle(ErrorCode errorCode, HttpServletRequest request) { + return ApiResponse.of( + ErrorResponse.of( + errorCode, request.getRequestURL().toString(), request.getMethod() + )); + } +} diff --git a/src/test/java/com/retrip/crew/domain/vo/CrewIntroductionTitleTest.java b/src/test/java/com/retrip/crew/domain/vo/CrewIntroductionTitleTest.java index 694e249..657c233 100644 --- a/src/test/java/com/retrip/crew/domain/vo/CrewIntroductionTitleTest.java +++ b/src/test/java/com/retrip/crew/domain/vo/CrewIntroductionTitleTest.java @@ -1,6 +1,6 @@ package com.retrip.crew.domain.vo; -import com.retrip.crew.domain.exception.CrewTitleException; +import com.retrip.crew.domain.exception.common.InvalidValueException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -11,6 +11,7 @@ class CrewIntroductionTitleTest { @Test @DisplayName("크루 이름은 30자 미만으로 설정해야한다.") public void validateName() { - assertThatThrownBy(() -> new CrewTitle("통천, 회양, 평강, 이천, 김화, 철원, 양구, 인제, 고성, 강릉, 속초 등 크루 인원 모집합니다.")).isExactlyInstanceOf(CrewTitleException.class); + assertThatThrownBy(() -> new CrewTitle("통천, 회양, 평강, 이천, 김화, 철원, 양구, 인제, 고성, 강릉, 속초 등 크루 인원 모집합니다.")) + .isExactlyInstanceOf(InvalidValueException.class); } } From fdf4dae7641a820d72699d0e9777c5a90ab9db60 Mon Sep 17 00:00:00 2001 From: mandykr Date: Wed, 26 Feb 2025 10:11:14 +0900 Subject: [PATCH 2/2] =?UTF-8?q?chore:=20=EC=98=A4=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/CrewNotFoundException.java | 2 +- .../exception/common/BusinessException.java | 6 ------ .../common/EntityNotFoundException.java | 2 +- .../domain/exception/common/ErrorCode.java | 4 ++-- .../in/presentation/rest/CrewController.java | 20 ------------------- 5 files changed, 4 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/retrip/crew/domain/exception/CrewNotFoundException.java b/src/main/java/com/retrip/crew/domain/exception/CrewNotFoundException.java index 868e539..002f158 100644 --- a/src/main/java/com/retrip/crew/domain/exception/CrewNotFoundException.java +++ b/src/main/java/com/retrip/crew/domain/exception/CrewNotFoundException.java @@ -4,7 +4,7 @@ import com.retrip.crew.domain.exception.common.ErrorCode; public class CrewNotFoundException extends EntityNotFoundException { - private static final ErrorCode errorCode = ErrorCode.CREW_NOT_FOUNT; + private static final ErrorCode errorCode = ErrorCode.CREW_NOT_FOUND; public CrewNotFoundException() { super(errorCode); diff --git a/src/main/java/com/retrip/crew/domain/exception/common/BusinessException.java b/src/main/java/com/retrip/crew/domain/exception/common/BusinessException.java index db24543..ea05e90 100644 --- a/src/main/java/com/retrip/crew/domain/exception/common/BusinessException.java +++ b/src/main/java/com/retrip/crew/domain/exception/common/BusinessException.java @@ -1,7 +1,6 @@ package com.retrip.crew.domain.exception.common; import lombok.Getter; -import lombok.NoArgsConstructor; @Getter public class BusinessException extends RuntimeException { @@ -12,11 +11,6 @@ public BusinessException(ErrorCode errorCode) { this.errorCode = errorCode; } - public BusinessException(String message, ErrorCode errorCode) { - super(message); - this.errorCode = errorCode; - } - public BusinessException(ErrorCode errorCode, String message) { super(message); this.errorCode = errorCode; diff --git a/src/main/java/com/retrip/crew/domain/exception/common/EntityNotFoundException.java b/src/main/java/com/retrip/crew/domain/exception/common/EntityNotFoundException.java index 33fc6ca..2c6d127 100644 --- a/src/main/java/com/retrip/crew/domain/exception/common/EntityNotFoundException.java +++ b/src/main/java/com/retrip/crew/domain/exception/common/EntityNotFoundException.java @@ -1,7 +1,7 @@ package com.retrip.crew.domain.exception.common; public class EntityNotFoundException extends BusinessException { - private static final ErrorCode errorCode = ErrorCode.ENTITY_NOT_FOUNT; + private static final ErrorCode errorCode = ErrorCode.ENTITY_NOT_FOUND; public EntityNotFoundException(ErrorCode errorCode) { super(errorCode); } diff --git a/src/main/java/com/retrip/crew/domain/exception/common/ErrorCode.java b/src/main/java/com/retrip/crew/domain/exception/common/ErrorCode.java index dda6974..520a72c 100644 --- a/src/main/java/com/retrip/crew/domain/exception/common/ErrorCode.java +++ b/src/main/java/com/retrip/crew/domain/exception/common/ErrorCode.java @@ -10,9 +10,9 @@ public enum ErrorCode { SERVER_ERROR(INTERNAL_SERVER_ERROR, "Common-001", "Server error"), INVALID_INPUT_VALUE(BAD_REQUEST, "Common-002", "Invalid input value"), HANDLE_ACCESS_DENIED(FORBIDDEN, "Common-003", "Access is denied"), - ENTITY_NOT_FOUNT(BAD_REQUEST, "Common-004", "Entity not found"), + ENTITY_NOT_FOUND(BAD_REQUEST, "Common-004", "Entity not found"), - CREW_NOT_FOUNT(BAD_REQUEST, "Crew-001", "크루 엔티티를 찾을 수 없습니다.") + CREW_NOT_FOUND(BAD_REQUEST, "Crew-001", "크루 엔티티를 찾을 수 없습니다.") ; private final HttpStatus status; diff --git a/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/CrewController.java b/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/CrewController.java index 99b4578..94d47bd 100644 --- a/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/CrewController.java +++ b/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/CrewController.java @@ -28,24 +28,4 @@ public ResponseEntity createCrew(@RequestBody CrewCreateRequ CrewCreateResponse crew = createCrewUseCase.createCrew(request); return ResponseEntity.created(URI.create("/crews/" + crew.id())).body(crew); } - - @PostMapping("/exception1") - public ApiResponse exception1(@RequestBody @Valid CrewCreateRequest request) { - throw new CrewNotFoundException(); - } - - @PostMapping("/exception2") - public ApiResponse exception2(@RequestBody @Valid CrewCreateRequest request) { - throw new InvalidValueException(ErrorCode.SERVER_ERROR); - } - - @PostMapping("/exception3") - public ApiResponse exception3(@RequestBody @Valid CrewCreateRequest request) { - throw new InvalidValueException("인풋 에러"); - } - - @PostMapping("/exception4") - public ApiResponse exception4(@RequestBody @Valid CrewCreateRequest request) { - throw new InvalidValueException(ErrorCode.SERVER_ERROR, "서버 에러"); - } }