-
Notifications
You must be signed in to change notification settings - Fork 0
[CHORE] 초기 프로젝트 설정 #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
949b62d
5e33843
3e7abe4
51883a6
841ac7a
5d94b2c
7856cf3
56f1956
339a7c5
958c1c9
51cd815
9b1b54b
60c14e9
a4b6c10
8868a7c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| ## #️⃣연관된 이슈 | ||
|
|
||
| > ex) #이슈번호, #이슈번호 | ||
|
|
||
| ## 📝작업 내용 | ||
|
|
||
| > 이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능) | ||
|
|
||
| ### 스크린샷 (선택) | ||
|
|
||
| ## 💬리뷰 요구사항(선택) | ||
|
|
||
| > 리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요 | ||
| > | ||
| > ex) 메서드 XXX의 이름을 더 잘 짓고 싶은데 혹시 좋은 명칭이 있을까요? |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| package konkuk.chacall.domain.test; | ||
|
|
||
| import jakarta.validation.Valid; | ||
| import jakarta.validation.constraints.Min; | ||
| import jakarta.validation.constraints.NotBlank; | ||
| import jakarta.validation.constraints.Size; | ||
| import konkuk.chacall.global.common.dto.BaseResponse; | ||
| import konkuk.chacall.global.common.exception.AuthException; | ||
| import konkuk.chacall.global.common.exception.BusinessException; | ||
| import konkuk.chacall.global.common.exception.DomainRuleException; | ||
| import konkuk.chacall.global.common.exception.EntityNotFoundException; | ||
| import konkuk.chacall.global.common.exception.code.ErrorCode; | ||
| import lombok.Getter; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/test") | ||
| public class TestController { | ||
|
|
||
| @GetMapping("/hello") | ||
| public String hello() { | ||
| return "Hello, World!"; | ||
| } | ||
|
|
||
| @GetMapping("/ping") | ||
| public BaseResponse<String> ping() { | ||
| return BaseResponse.ok("pong"); | ||
| } | ||
|
|
||
| // === 커스텀 예외들 === | ||
| @GetMapping("/auth-error") | ||
| public String authError() { | ||
| throw new AuthException(ErrorCode.AUTH_UNAUTHORIZED); | ||
| } | ||
|
Comment on lines
+20
to
+34
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 커스텀 예외들을 확인할 수 있는 테스트용 컨트롤러들 만드신 것 좋네요! |
||
|
|
||
| @GetMapping("/entity-error") | ||
| public String entityError() { | ||
| throw new EntityNotFoundException(ErrorCode.USER_NOT_FOUND); | ||
| } | ||
|
|
||
| @GetMapping("/domain-error") | ||
| public String domainError() { | ||
| throw new DomainRuleException(ErrorCode.USER_ALREADY_EXISTS); | ||
| } | ||
|
|
||
| @GetMapping("/business-error") | ||
| public String businessError() { | ||
| throw new BusinessException(ErrorCode.USER_NICKNAME_DUPLICATION); | ||
| } | ||
|
|
||
| @GetMapping("/runtime-error") | ||
| public String runtimeError() { | ||
| throw new RuntimeException("강제 RuntimeException 발생"); | ||
| } | ||
|
|
||
| // === GlobalExceptionHandler 내장 케이스들 === | ||
|
|
||
| // 1. MethodArgumentNotValidException 테스트 (@Valid DTO 사용) | ||
| @PostMapping("/validate-body") | ||
| public String validateBody(@Valid @RequestBody UserRequest request) { | ||
| return "유효성 통과: " + request.toString(); | ||
| } | ||
|
|
||
| // 2. MethodArgumentTypeMismatchException 테스트 | ||
| // 호출: /test/type-mismatch?id=문자열 | ||
| @GetMapping("/type-mismatch") | ||
| public String typeMismatch(@RequestParam("id") Long id) { | ||
| return "입력한 id: " + id; | ||
| } | ||
|
|
||
| // 3. MissingServletRequestParameterException 테스트 | ||
| // 호출 시 /test/missing-param 만 요청 -> user 파라미터 없음 | ||
| @GetMapping("/missing-param") | ||
| public String missingParam(@RequestParam("user") String user) { | ||
| return "user: " + user; | ||
| } | ||
|
|
||
| // 4. ConstraintViolationException 테스트 | ||
| // 호출: /test/constraint?id=-5 | ||
| @GetMapping("/constraint") | ||
| public String constraint(@RequestParam("id") @Valid @Min(1) int id) { | ||
| return "id: " + id; | ||
| } | ||
|
|
||
| // DTO 내부 유효성 검증용 클래스 | ||
| @Getter | ||
| private static class UserRequest { | ||
| @NotBlank(message = "이름은 필수 값입니다.") | ||
| private String name; | ||
|
|
||
| @Size(min = 5, max = 20, message = "닉네임은 5~20자 사이여야 합니다.") | ||
| private String nickname; | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return "UserRequest{name='" + name + "', nickname='" + nickname + "'}"; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| package konkuk.chacall.global.common.dto; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonProperty; | ||
| import com.fasterxml.jackson.annotation.JsonPropertyOrder; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| @JsonPropertyOrder({"isSuccess", "code", "message", "data"}) | ||
| public class BaseResponse<T> { | ||
|
|
||
| @JsonProperty("isSuccess") | ||
| private final boolean success; | ||
|
|
||
| private final int code; | ||
|
|
||
| private final String message; | ||
|
|
||
| private final T data; | ||
|
|
||
| private BaseResponse(boolean success, int code, String message, T data) { | ||
| this.success = success; | ||
| this.code = code; | ||
| this.message = message; | ||
| this.data = data; | ||
| } | ||
|
|
||
| private BaseResponse(ResponseCode response, T data) { | ||
| this(response.isSuccess(), response.getCode(), response.getMessage(), data); | ||
| } | ||
|
|
||
| public static <T> BaseResponse<T> ok(T data) { | ||
| return new BaseResponse<>(SuccessCode.API_SUCCESS, data); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| package konkuk.chacall.global.common.dto; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonProperty; | ||
| import com.fasterxml.jackson.annotation.JsonPropertyOrder; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| @JsonPropertyOrder({"isSuccess", "code", "message"}) | ||
| public class ErrorResponse { | ||
|
|
||
| @JsonProperty("isSuccess") | ||
| private final boolean success; | ||
|
|
||
| private final int code; | ||
|
|
||
| private final String message; | ||
|
|
||
| private ErrorResponse(boolean success, int code, String message) { | ||
| this.success = success; | ||
| this.code = code; | ||
| this.message = message; | ||
| } | ||
|
|
||
| private ErrorResponse(ResponseCode response) { | ||
| this(response.isSuccess(), response.getCode(), response.getMessage()); | ||
| } | ||
|
|
||
| public static ErrorResponse of(ResponseCode response) { | ||
| return new ErrorResponse(response); | ||
| } | ||
|
|
||
| public static ErrorResponse of(ResponseCode response, String message) { | ||
| StringBuilder sb = new StringBuilder(); | ||
| sb.append(response.getMessage()).append(" ").append(message); | ||
| return new ErrorResponse(response.isSuccess(), response.getCode(), sb.toString()); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package konkuk.chacall.global.common.dto; | ||
|
|
||
| public interface ResponseCode { | ||
| int getCode(); | ||
|
|
||
| String getMessage(); | ||
|
|
||
| default boolean isSuccess() { | ||
| return this instanceof SuccessCode; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package konkuk.chacall.global.common.dto; | ||
|
|
||
| import konkuk.chacall.global.common.dto.ResponseCode; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public enum SuccessCode implements ResponseCode { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 성공 케이스도 세분화하는 형식이군여 확인했습니다!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 음 공통적으로 HttpStatus 200일 때는 |
||
| API_SUCCESS(20000, "요청에 성공했습니다."), | ||
| ; | ||
|
|
||
| private final int code; | ||
| private final String message; | ||
|
|
||
| SuccessCode(int code, String message) { | ||
| this.code = code; | ||
| this.message = message; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,18 @@ | ||||||||||||||||||||||||||||||||||||
| package konkuk.chacall.global.common.exception; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| import konkuk.chacall.global.common.exception.code.ErrorCode; | ||||||||||||||||||||||||||||||||||||
| import lombok.Getter; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Getter | ||||||||||||||||||||||||||||||||||||
| public class AuthException extends RuntimeException { | ||||||||||||||||||||||||||||||||||||
| private final ErrorCode errorCode; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| public AuthException(ErrorCode errorCode) { | ||||||||||||||||||||||||||||||||||||
| this.errorCode = errorCode; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| public AuthException(ErrorCode errorCode, Exception e) { | ||||||||||||||||||||||||||||||||||||
| super(e); | ||||||||||||||||||||||||||||||||||||
| this.errorCode = errorCode; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+10
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 예외 메시지 누락: super(message)로 로깅 가시성 확보 현재 - public AuthException(ErrorCode errorCode) {
- this.errorCode = errorCode;
- }
+ public AuthException(ErrorCode errorCode) {
+ super(errorCode.getMessage());
+ this.errorCode = errorCode;
+ }
- public AuthException(ErrorCode errorCode, Exception e) {
- super(e);
- this.errorCode = errorCode;
- }
+ public AuthException(ErrorCode errorCode, Exception e) {
+ super(errorCode.getMessage(), e);
+ this.errorCode = errorCode;
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package konkuk.chacall.global.common.exception; | ||
|
|
||
| import konkuk.chacall.global.common.exception.code.ErrorCode; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public class BusinessException extends RuntimeException { | ||
| private final ErrorCode errorCode; | ||
|
|
||
| public BusinessException(ErrorCode errorCode) { | ||
| super(errorCode.getMessage()); | ||
| this.errorCode = errorCode; | ||
| } | ||
|
|
||
| public BusinessException(ErrorCode errorCode, Exception e) { | ||
| super(errorCode.getMessage(), e); | ||
| this.errorCode = errorCode; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package konkuk.chacall.global.common.exception; | ||
|
|
||
| import konkuk.chacall.global.common.exception.code.ErrorCode; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public class DomainRuleException extends BusinessException { | ||
| public DomainRuleException(ErrorCode errorCode) { | ||
| super(errorCode); | ||
| } | ||
|
|
||
| public DomainRuleException(ErrorCode errorCode, Exception e) { | ||
| super(errorCode, e); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package konkuk.chacall.global.common.exception; | ||
|
|
||
|
|
||
| import konkuk.chacall.global.common.exception.code.ErrorCode; | ||
|
|
||
| public class EntityNotFoundException extends BusinessException { | ||
|
|
||
| public EntityNotFoundException(ErrorCode errorCode) { | ||
| super(errorCode); | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.