Skip to content

Commit 4db41cb

Browse files
committed
[feat] 여러 Exception 핸들러 추가
1 parent 2e8310c commit 4db41cb

3 files changed

Lines changed: 87 additions & 13 deletions

File tree

src/main/java/com/arom/with_travel/global/exception/error/ErrorCode.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,24 @@
77
@AllArgsConstructor
88
public enum ErrorCode {
99

10-
TMP_ERROR("S3-0000", "파일 형식이 올바르지 않습니다.", ErrorDisplayType.MODAL),
10+
// Common Error
11+
INTERNAL_SERVER_ERROR("C001", "Server Error", ErrorDisplayType.POPUP),
12+
INVALID_INPUT_VALUE("C002", "Invalid Input Value",ErrorDisplayType.POPUP ),
13+
METHOD_NOT_ALLOWED("C003", "Invalid HTTP Method", ErrorDisplayType.POPUP),
14+
ENTITY_NOT_FOUND("C004", "Entity Not Found", ErrorDisplayType.POPUP ),
15+
CONFLICT("C005", "Conflict Occurred", ErrorDisplayType.POPUP),
16+
UNACCEPTABLE_EXTENSION("C007", "Unacceptable Extension",ErrorDisplayType.POPUP ),
17+
INVALID_JSON_FORMAT("C008", "Invalid JSON Format",ErrorDisplayType.POPUP ),
18+
MISSING_PARAMETER("C009", "Missing Parameter",ErrorDisplayType.POPUP ),
19+
INVALID_PARAMETER_TYPE("C010", "Invalid Parameter Type",ErrorDisplayType.POPUP ),
20+
MISSING_PATH_VARIABLE("C011", "Missing Path Variable", ErrorDisplayType.POPUP),
21+
FORBIDDEN("C012", "Forbidden", ErrorDisplayType.POPUP),
22+
ERR_DATA_INTEGRITY_VIOLATION("E001", "Data integrity violation", ErrorDisplayType.POPUP),
23+
VALIDATION_FAILED("C013", "Validation Failed", ErrorDisplayType.POPUP),
24+
25+
// Validation
26+
REQ_BODY_ERROR("REQ-0000", "", ErrorDisplayType.POPUP),
27+
REQ_PARAMS_ERROR("REQ-0001", "", ErrorDisplayType.POPUP),
1128

1229
//member
1330
MEMBER_NOT_FOUND("MEM-0000", "해당 회원이 존재하지 않습니다.", ErrorDisplayType.POPUP),

src/main/java/com/arom/with_travel/global/exception/handler/GlobalExceptionHandler.java

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,80 @@
44
import com.arom.with_travel.global.exception.error.ErrorCode;
55
import com.arom.with_travel.global.exception.error.ErrorDisplayType;
66
import com.arom.with_travel.global.exception.response.ErrorResponse;
7+
import jakarta.validation.ConstraintViolationException;
78
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.beans.TypeMismatchException;
10+
import org.springframework.context.MessageSourceResolvable;
11+
import org.springframework.dao.DataIntegrityViolationException;
12+
import org.springframework.http.ResponseEntity;
13+
import org.springframework.http.converter.HttpMessageNotReadableException;
14+
import org.springframework.web.HttpRequestMethodNotSupportedException;
815
import org.springframework.web.bind.MethodArgumentNotValidException;
16+
import org.springframework.web.bind.MissingServletRequestParameterException;
917
import org.springframework.web.bind.annotation.ExceptionHandler;
1018
import org.springframework.web.bind.annotation.RestController;
1119
import org.springframework.web.bind.annotation.RestControllerAdvice;
20+
import org.springframework.web.method.annotation.HandlerMethodValidationException;
1221

1322
@Slf4j
1423
@RestControllerAdvice(annotations = {RestController.class})
1524
public class GlobalExceptionHandler {
1625

17-
/**
18-
* 클라이언트 에러
19-
* 직접 생성한 예외에 대한 처리
20-
*/
26+
// HTTP Method 불일치 에러
27+
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
28+
public ErrorResponse handleHttpRequestMethodNotSupportedException(
29+
HttpRequestMethodNotSupportedException e) {
30+
return ErrorResponse.generateFrom(ErrorCode.METHOD_NOT_ALLOWED);
31+
}
32+
33+
// @RequestBody JSON 파싱 에러
34+
@ExceptionHandler(HttpMessageNotReadableException.class)
35+
public ErrorResponse handleJsonParseException(HttpMessageNotReadableException e) {
36+
return ErrorResponse.generateFrom(ErrorCode.INVALID_JSON_FORMAT);
37+
}
38+
39+
// 필수 @RequestParam 누락
40+
@ExceptionHandler(MissingServletRequestParameterException.class)
41+
public ErrorResponse handleMissingParam(MissingServletRequestParameterException e) {
42+
return ErrorResponse.generateFrom(ErrorCode.MISSING_PARAMETER);
43+
}
44+
45+
// @RequestParam 타입 불일치
46+
@ExceptionHandler(TypeMismatchException.class)
47+
public ErrorResponse handleTypeMismatchException(TypeMismatchException e) {
48+
return ErrorResponse.generateFrom(ErrorCode.INVALID_PARAMETER_TYPE);
49+
}
50+
51+
// 데이터 무결성 위반
52+
@ExceptionHandler(DataIntegrityViolationException.class)
53+
public ErrorResponse handleDataIntegrityViolationException(DataIntegrityViolationException ex) {
54+
return ErrorResponse.generateFrom(ErrorCode.ERR_DATA_INTEGRITY_VIOLATION);
55+
}
56+
2157
@ExceptionHandler(BaseException.class)
2258
public ErrorResponse onThrowException(BaseException baseException) {
23-
return ErrorResponse.generateErrorResponse(baseException);
59+
return ErrorResponse.generateFrom(baseException);
2460
}
2561

26-
// TODO : 바인딩 에러 관련 ErrorCode 작성
2762
@ExceptionHandler(MethodArgumentNotValidException.class)
2863
public ErrorResponse onThrowException(MethodArgumentNotValidException exception){
29-
return ErrorResponse.builder()
30-
.code(ErrorCode.TMP_ERROR.getCode())
31-
.message(exception.getBindingResult().getFieldError().getDefaultMessage())
32-
.displayType(ErrorDisplayType.POPUP)
33-
.build();
64+
String message = exception.getBindingResult().getFieldError().getDefaultMessage();
65+
return ErrorResponse.generateWithCustomMessage(ErrorCode.REQ_BODY_ERROR, message);
66+
}
67+
68+
@ExceptionHandler(HandlerMethodValidationException.class)
69+
public ErrorResponse onThrowException(HandlerMethodValidationException exception){
70+
String message = exception
71+
.getAllErrors()
72+
.stream()
73+
.map(MessageSourceResolvable::getDefaultMessage)
74+
.findFirst()
75+
.orElse("Validation Failed");
76+
return ErrorResponse.generateWithCustomMessage(ErrorCode.REQ_PARAMS_ERROR, message);
77+
}
78+
79+
@ExceptionHandler(Exception.class)
80+
protected ErrorResponse handleException(Exception e) {
81+
return ErrorResponse.generateFrom(ErrorCode.INTERNAL_SERVER_ERROR);
3482
}
3583
}

src/main/java/com/arom/with_travel/global/exception/response/ErrorResponse.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.arom.with_travel.global.exception.response;
22

33
import com.arom.with_travel.global.exception.BaseException;
4+
import com.arom.with_travel.global.exception.error.ErrorCode;
45
import com.arom.with_travel.global.exception.error.ErrorDisplayType;
56
import com.fasterxml.jackson.annotation.JsonProperty;
67
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@@ -20,7 +21,15 @@ public class ErrorResponse {
2021
private final String message;
2122
private final ErrorDisplayType displayType;
2223

23-
public static ErrorResponse generateErrorResponse(BaseException baseException){
24+
public static ErrorResponse generateFrom(ErrorCode errorCode) {
25+
return new ErrorResponse(errorCode.getCode(), errorCode.getMessage(), errorCode.getDisplayType());
26+
}
27+
28+
public static ErrorResponse generateWithCustomMessage(ErrorCode errorCode, String customMessage) {
29+
return new ErrorResponse(errorCode.getCode(), customMessage, errorCode.getDisplayType());
30+
}
31+
32+
public static ErrorResponse generateFrom(BaseException baseException){
2433
if(baseException.hasCustomMessage()) {
2534
return new ErrorResponse(
2635
baseException.getErrorCode().getCode(),

0 commit comments

Comments
 (0)