Skip to content

Commit 8114fec

Browse files
committed
fix: requestBody 파싱 실패 예외처리 추가
1 parent 00f8415 commit 8114fec

File tree

2 files changed

+50
-21
lines changed

2 files changed

+50
-21
lines changed

src/main/java/com/devpath/global/apiPayload/code/status/GeneralErrorCode.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public enum GeneralErrorCode implements BaseErrorCode {
2020
_UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "COMMON_401", "인증이 필요합니다."),
2121
_FORBIDDEN(HttpStatus.FORBIDDEN, "COMMON_403", "금지된 요청입니다."),
2222
_NO_RESULTS_FOUND(HttpStatus.NOT_FOUND, "COMMON_404", "검색 결과가 없습니다."),
23+
_INVALID_INPUT(HttpStatus.BAD_REQUEST,"COMMON_405","입력값이 올바르지 않습니다."),
2324
_INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "COMMON_500", "서버 에러. 관리자에게 문의 바랍니다."),;
2425

2526
private final HttpStatus httpStatus;

src/main/java/com/devpath/global/apiPayload/exception/ExceptionAdvice.java

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,28 @@
1111
import org.springframework.http.HttpStatus;
1212
import org.springframework.http.HttpStatusCode;
1313
import org.springframework.http.ResponseEntity;
14+
import org.springframework.http.converter.HttpMessageNotReadableException;
1415
import org.springframework.web.bind.MethodArgumentNotValidException;
1516
import org.springframework.web.bind.annotation.ExceptionHandler;
1617
import org.springframework.web.bind.annotation.RestController;
1718
import org.springframework.web.bind.annotation.RestControllerAdvice;
1819
import org.springframework.web.context.request.ServletWebRequest;
1920
import org.springframework.web.context.request.WebRequest;
21+
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
2022
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
2123

2224
import java.util.LinkedHashMap;
2325
import java.util.Map;
2426
import java.util.Optional;
2527

2628
@Slf4j
27-
@RestControllerAdvice(annotations = {RestController.class})
29+
@RestControllerAdvice(annotations = { RestController.class })
2830
public class ExceptionAdvice extends ResponseEntityExceptionHandler {
2931

32+
/**
33+
* @Valid 어노테이션을 통한 검증 실패 시 발생합니다.
34+
* 주로 @RequestParam, @PathVariable 검증 실패 시 발생합니다.
35+
*/
3036
@ExceptionHandler
3137
public ResponseEntity<Object> validation(ConstraintViolationException e, WebRequest request) {
3238
String errorMessage = e.getConstraintViolations().stream()
@@ -37,36 +43,61 @@ public ResponseEntity<Object> validation(ConstraintViolationException e, WebRequ
3743
return handleExceptionInternalConstraint(e, GeneralErrorCode.valueOf(errorMessage), HttpHeaders.EMPTY, request);
3844
}
3945

46+
/**
47+
* @Valid 어노테이션을 통한 검증 실패 시 발생합니다.
48+
* 주로 @RequestBody 검증 실패 시 발생합니다.
49+
*/
4050
@Override
41-
public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException e, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
51+
public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException e, HttpHeaders headers,
52+
HttpStatusCode status, WebRequest request) {
4253
Map<String, String> errors = new LinkedHashMap<>();
4354

4455
e.getBindingResult().getFieldErrors()
4556
.forEach(fieldError -> {
4657
String fieldName = fieldError.getField();
4758
String errorMessage = Optional.ofNullable(fieldError.getDefaultMessage()).orElse("");
48-
errors.merge(fieldName, errorMessage, (existingErrorMessage, newErrorMessage) -> existingErrorMessage + ", " + newErrorMessage);
59+
errors.merge(fieldName, errorMessage,
60+
(existingErrorMessage, newErrorMessage) -> existingErrorMessage + ", " + newErrorMessage);
4961
});
5062

51-
return handleExceptionInternalArgs(e, HttpHeaders.EMPTY, GeneralErrorCode.valueOf("_BAD_REQUEST"), request, errors);
63+
return handleExceptionInternalArgs(e, HttpHeaders.EMPTY, GeneralErrorCode.valueOf("_BAD_REQUEST"), request,
64+
errors);
5265
}
5366

67+
/**
68+
* JSON Request Body 파싱 실패 시 발생합니다.
69+
* 주로 잘못된 형식의 JSON이나 Enum 타입 불일치 시 발생합니다.
70+
*/
71+
@Override
72+
public ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException e, HttpHeaders headers,
73+
HttpStatusCode status, WebRequest request) {
74+
return handleExceptionInternalConstraint(e, GeneralErrorCode._INVALID_INPUT, headers, request);
75+
}
76+
77+
/**
78+
* 처리되지 않은 모든 예외를 처리합니다.
79+
* 500 Internal Server Error를 반환합니다.
80+
*/
5481
@ExceptionHandler
5582
public ResponseEntity<Object> exception(Exception e, WebRequest request) {
56-
log.error("500 Error",e);
57-
return handleExceptionInternalFalse(e, GeneralErrorCode._INTERNAL_SERVER_ERROR.getHttpStatus(), request, e.getMessage());
83+
log.error("500 Error", e);
84+
return handleExceptionInternalFalse(e, GeneralErrorCode._INTERNAL_SERVER_ERROR.getHttpStatus(), request,
85+
e.getMessage());
5886
}
5987

60-
// 비즈니스 로직 커스텀 예외처리
88+
/**
89+
* 비즈니스 로직 실행 중 발생하는 커스텀 예외를 처리합니다.
90+
*/
6191
@ExceptionHandler(value = GeneralException.class)
6292
public ResponseEntity onThrowException(GeneralException generalException, HttpServletRequest request) {
6393
return handleExceptionInternal(generalException,
6494
generalException.getCode(),
6595
HttpHeaders.EMPTY,
6696
request);
6797
}
98+
6899
private ResponseEntity<Object> handleExceptionInternal(Exception e, BaseErrorCode reason,
69-
HttpHeaders headers, HttpServletRequest request) {
100+
HttpHeaders headers, HttpServletRequest request) {
70101

71102
ApiResponse<Object> body = ApiResponse.onFailure(reason, reason.getMessage());
72103

@@ -76,43 +107,40 @@ private ResponseEntity<Object> handleExceptionInternal(Exception e, BaseErrorCod
76107
body,
77108
headers,
78109
reason.getHttpStatus(),
79-
webRequest
80-
);
110+
webRequest);
81111
}
82112

83113
private ResponseEntity<Object> handleExceptionInternalFalse(Exception e,
84-
HttpStatus status, WebRequest request, String errorPoint) {
85-
ApiResponse<Object> body = ApiResponse.onFailure(GeneralErrorCode._INTERNAL_SERVER_ERROR,errorPoint);
114+
HttpStatus status, WebRequest request, String errorPoint) {
115+
ApiResponse<Object> body = ApiResponse.onFailure(GeneralErrorCode._INTERNAL_SERVER_ERROR, errorPoint);
86116
return super.handleExceptionInternal(
87117
e,
88118
body,
89119
HttpHeaders.EMPTY,
90120
status,
91-
request
92-
);
121+
request);
93122
}
94123

95-
private ResponseEntity<Object> handleExceptionInternalArgs(Exception e, HttpHeaders headers, GeneralErrorCode errorCommonStatus,
96-
WebRequest request, Map<String, String> errorArgs) {
124+
private ResponseEntity<Object> handleExceptionInternalArgs(Exception e, HttpHeaders headers,
125+
GeneralErrorCode errorCommonStatus,
126+
WebRequest request, Map<String, String> errorArgs) {
97127
ApiResponse<Object> body = ApiResponse.onFailure(errorCommonStatus, errorArgs);
98128
return super.handleExceptionInternal(
99129
e,
100130
body,
101131
headers,
102132
errorCommonStatus.getHttpStatus(),
103-
request
104-
);
133+
request);
105134
}
106135

107136
private ResponseEntity<Object> handleExceptionInternalConstraint(Exception e, GeneralErrorCode errorCommonStatus,
108-
HttpHeaders headers, WebRequest request) {
137+
HttpHeaders headers, WebRequest request) {
109138
ApiResponse<Object> body = ApiResponse.onFailure(errorCommonStatus, null);
110139
return super.handleExceptionInternal(
111140
e,
112141
body,
113142
headers,
114143
errorCommonStatus.getHttpStatus(),
115-
request
116-
);
144+
request);
117145
}
118146
}

0 commit comments

Comments
 (0)