-
Notifications
You must be signed in to change notification settings - Fork 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
[feat] global response 추가 #13
Changes from all commits
237ef73
a0f3fbf
df729c1
466ba41
fd4c853
0079ea2
964c523
ebdae5a
3b9f161
1afef9b
7a3e72f
464c374
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,20 @@ | ||
package com.ourmenu.backend.global.exception; | ||
|
||
public class CustomException extends RuntimeException { | ||
|
||
private final ErrorCode errorCode; | ||
|
||
public CustomException(String message, ErrorCode errorCode) { | ||
super(message); | ||
this.errorCode = errorCode; | ||
} | ||
|
||
public CustomException(ErrorCode errorCode) { | ||
super(errorCode.getMessage()); | ||
this.errorCode = errorCode; | ||
} | ||
|
||
public ErrorCode getErrorCode() { | ||
return errorCode; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.ourmenu.backend.global.exception; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import org.springframework.http.HttpStatus; | ||
|
||
@AllArgsConstructor | ||
@Getter | ||
public enum ErrorCode { | ||
|
||
INTERNAL_SERVER(HttpStatus.INTERNAL_SERVER_ERROR, "G500", "서버 내부에서 에러가 발생하였습니다"); | ||
|
||
private final HttpStatus httpStatus; | ||
|
||
private final String code; | ||
|
||
private final String message; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.ourmenu.backend.global.exception; | ||
|
||
import lombok.Builder; | ||
|
||
@Builder | ||
public record ErrorResponse(int status, String code, String message) { | ||
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. DTO에서 record 클래스를 사용하는 방법 좋은 것 같아요 |
||
|
||
public static ErrorResponse of(ErrorCode errorCode) { | ||
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. 이와 같이 DTO에서 Response를 build하는 메소드를 정의해놓으면 Service 레이어의 코드가 간결해질 것 같네요! 👍👍 |
||
return ErrorResponse.builder() | ||
.status(errorCode.getHttpStatus().value()) | ||
.code(errorCode.getCode()) | ||
.message(errorCode.getMessage()) | ||
.build(); | ||
} | ||
|
||
public static ErrorResponse of(String message, ErrorCode errorCode) { | ||
return ErrorResponse.builder() | ||
.status(errorCode.getHttpStatus().value()) | ||
.code(errorCode.getCode()) | ||
.message(message) | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.ourmenu.backend.global.exception; | ||
|
||
import com.ourmenu.backend.global.response.ApiResponse; | ||
import com.ourmenu.backend.global.response.util.ApiUtil; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.RestControllerAdvice; | ||
|
||
@RestControllerAdvice | ||
@Slf4j | ||
public class GlobalExceptionHandler { | ||
|
||
@ExceptionHandler(RuntimeException.class) | ||
public ApiResponse<?> handleException(RuntimeException e) { | ||
return handleException(e, ErrorResponse.of(ErrorCode.INTERNAL_SERVER)); | ||
} | ||
|
||
@ExceptionHandler(CustomException.class) | ||
public ApiResponse<?> handleCustomException(CustomException e) { | ||
return handleException(e, ErrorResponse.of(e.getMessage(), e.getErrorCode())); | ||
} | ||
|
||
public ApiResponse<?> handleException(Exception e, ErrorResponse errorResponse) { | ||
log.error("{}: {}", errorResponse.code(), e.getMessage()); | ||
return ApiUtil.error(errorResponse); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.ourmenu.backend.global.response; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import com.ourmenu.backend.global.exception.ErrorResponse; | ||
import lombok.AllArgsConstructor; | ||
|
||
@AllArgsConstructor | ||
public class ApiResponse<T> { | ||
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. 여기도 @AllArgsConstructor 어노테이션을 사용할 수 있을 것 같아요 |
||
|
||
private final boolean isSuccess; | ||
|
||
@JsonProperty(value = "response") | ||
private final T response; | ||
|
||
@JsonProperty(value = "errorResponse") | ||
private final ErrorResponse errorResponse; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.ourmenu.backend.global.response.util; | ||
|
||
import com.ourmenu.backend.global.exception.ErrorResponse; | ||
import com.ourmenu.backend.global.response.ApiResponse; | ||
|
||
public class ApiUtil { | ||
|
||
private ApiUtil() { | ||
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. 정적 유틸리티 클래스 구조를 잘 구현해주신 것 같아요. 유틸 클래스는 객체지향적 프로그래밍이 아니라는 문제점이 있는데, 이에 대한 의견과 Spirng Bean으로 등록하는 방법에 대해 어떻게 생각하시는지 궁금합니다! 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. 정적 유틸 클래스는 분명 OOP를 벗어난 영역입니다. 구현하면서도 정적 클래스를 최대한 지양하는게 맞다고 생각했습니다. ApiUtil은 ApiResponse을 반환하는 역활을 가지고 있습니다. 분명 객체가 할 수 있는 영역입니다. 다만 진행하고 있는 프로젝트에서의 ApiUtil은 모든 엔드포인트 종단점에서 호출되어야하고. 만약 객체로 선언한다라면 메인 도메인 로직에서 불필요한 객체 선언을 계속 해야한다는 점에서 유틸클래스로 구현하게 되었어요. |
||
} | ||
|
||
public static <T> ApiResponse<T> success(T response) { | ||
return new ApiResponse<>(true, response, null); | ||
} | ||
|
||
public static ApiResponse<?> error(ErrorResponse errorResponse) { | ||
return new ApiResponse<>(false, null, errorResponse); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AllArgsConstructor 와 @Getter 어노테이션을 사용한다면 코드가 간결해질 것 같아요