diff --git a/src/main/java/com/noplanb/global/payload/ErrorCode.java b/src/main/java/com/noplanb/global/payload/ErrorCode.java index 91ab2cc..ce397e1 100644 --- a/src/main/java/com/noplanb/global/payload/ErrorCode.java +++ b/src/main/java/com/noplanb/global/payload/ErrorCode.java @@ -1,24 +1,30 @@ package com.noplanb.global.payload; import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; @Getter +@RequiredArgsConstructor public enum ErrorCode { - INVALID_PARAMETER(400, null, "잘못된 요청 데이터 입니다."), - INVALID_REPRESENTATION(400, null, "잘못된 표현 입니다."), - INVALID_FILE_PATH(400, null, "잘못된 파일 경로 입니다."), - INVALID_OPTIONAL_ISPRESENT(400, null, "해당 값이 존재하지 않습니다."), - INVALID_CHECK(400, null, "해당 값이 유효하지 않습니다."), - INVALID_AUTHENTICATION(400, null, "잘못된 인증입니다."); + INVALID_INPUT_VALUE(HttpStatus.BAD_REQUEST, "E1", "올바르지 않은 입력값입니다."), + METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "E2", "잘못된 HTTP 메서드를 호출했습니다."), + INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "E3", "서버 에러가 발생했습니다."), + NOT_FOUND(HttpStatus.NOT_FOUND, "E4", "존재하지 않는 엔티티입니다."), + CHARACTER_NOT_FOUND(HttpStatus.NOT_FOUND, "A1", "존재하지 않는 캐릭터입니다."); + - private final String code; private final String message; - private final int status; - ErrorCode(final int status, final String code, final String message) { + private final String code; + private final HttpStatus status; + + ErrorCode(final HttpStatus status, final String code, final String message) { +// System.out.println("message = " + message); this.status = status; - this.message = message; this.code = code; + this.message = message; } + } diff --git a/src/main/java/com/noplanb/global/payload/ErrorResponse.java b/src/main/java/com/noplanb/global/payload/ErrorResponse.java index 67e315f..6f11c1e 100644 --- a/src/main/java/com/noplanb/global/payload/ErrorResponse.java +++ b/src/main/java/com/noplanb/global/payload/ErrorResponse.java @@ -1,77 +1,31 @@ package com.noplanb.global.payload; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Builder; -import lombok.Data; -import org.springframework.validation.FieldError; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.validation.BindingResult; -import java.time.LocalDateTime; -import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; -@Data +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class ErrorResponse { - private LocalDateTime timestamp = LocalDateTime.now(); private String message; - private String code; - - @JsonProperty("class") - private String clazz; - - private int status; - - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonProperty("errors") - private List customFieldErrors = new ArrayList<>(); - - public ErrorResponse() {} - - @Builder - public ErrorResponse(String code, int status, String message, String clazz, List fieldErrors){ - this.code = code; - this.status = status; + private ErrorResponse(final ErrorCode code) { + this.message = code.getMessage(); + this.code = code.getCode(); + } + public ErrorResponse(final ErrorCode code, final String message) { this.message = message; - this.clazz = clazz; - setFieldErrors(fieldErrors); + this.code = code.getCode(); } - - public void setFieldErrors(List fieldErrors) { - if(fieldErrors != null){ - fieldErrors.forEach(error -> { - customFieldErrors.add(new CustomFieldError( - error.getField(), - error.getRejectedValue(), - error.getDefaultMessage() - )); - }); - } + public static ErrorResponse of(final ErrorCode code) { + return new ErrorResponse(code); } - - public static class CustomFieldError { - - private String field; - private Object value; - private String reason; - - public CustomFieldError(String field, Object value, String reason) { - this.field = field; - this.value = value; - this.reason = reason; - } - - public String getField() { - return field; - } - - public Object getValue() { - return value; - } - - public String getReason() { - return reason; - } + public static ErrorResponse of(final ErrorCode code, final String message) { + return new ErrorResponse(code, message); } -} +} \ No newline at end of file diff --git a/src/main/java/com/noplanb/global/payload/exception/BusinessBaseException.java b/src/main/java/com/noplanb/global/payload/exception/BusinessBaseException.java new file mode 100644 index 0000000..dfc4b40 --- /dev/null +++ b/src/main/java/com/noplanb/global/payload/exception/BusinessBaseException.java @@ -0,0 +1,22 @@ +package com.noplanb.global.payload.exception; + +import com.noplanb.global.payload.ErrorCode; + +public class BusinessBaseException extends RuntimeException { + + private final ErrorCode errorCode; + + public BusinessBaseException(String message, ErrorCode errorCode) { + super(message); + this.errorCode = errorCode; + } + + public BusinessBaseException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode = errorCode; + } + + public ErrorCode getErrorCode() { + return errorCode; + } +} diff --git a/src/main/java/com/noplanb/global/payload/exception/CharacterNotFoundException.java b/src/main/java/com/noplanb/global/payload/exception/CharacterNotFoundException.java new file mode 100644 index 0000000..67b7ade --- /dev/null +++ b/src/main/java/com/noplanb/global/payload/exception/CharacterNotFoundException.java @@ -0,0 +1,11 @@ +package com.noplanb.global.payload.exception; + +import com.noplanb.global.payload.ErrorCode; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CharacterNotFoundException extends NotFoundException{ + public CharacterNotFoundException(){ + super(ErrorCode.CHARACTER_NOT_FOUND); + } +} diff --git a/src/main/java/com/noplanb/global/payload/exception/GlobalExceptionHandler.java b/src/main/java/com/noplanb/global/payload/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..3b12d2a --- /dev/null +++ b/src/main/java/com/noplanb/global/payload/exception/GlobalExceptionHandler.java @@ -0,0 +1,42 @@ +package com.noplanb.global.payload.exception; + +import com.noplanb.global.payload.ErrorCode; +import com.noplanb.global.payload.ErrorResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@Slf4j +//@ControllerAdvice // 모든 컨트롤러에서 발생하는 예외를 잡아서 처리 +@RestControllerAdvice +public class GlobalExceptionHandler { + + // 지원하지 않은 HTTP method 호출 할 경우 발생 + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) // HttpRequestMethodNotSupportedException 예외를 잡아서 처리 + protected ResponseEntity handle(HttpRequestMethodNotSupportedException e) { + log.error("HttpRequestMethodNotSupportedException", e); + return createErrorResponseEntity(ErrorCode.METHOD_NOT_ALLOWED); + } + + @ExceptionHandler(BusinessBaseException.class) + protected ResponseEntity handle(BusinessBaseException e) { + log.error("BusinessException", e); + return createErrorResponseEntity(e.getErrorCode()); + } + + @ExceptionHandler(Exception.class) + protected ResponseEntity handle(Exception e) { + e.printStackTrace(); + log.error("Exception", e); + return createErrorResponseEntity(ErrorCode.INTERNAL_SERVER_ERROR); + } + + private ResponseEntity createErrorResponseEntity(ErrorCode errorCode) { + return new ResponseEntity<>( + ErrorResponse.of(errorCode), + errorCode.getStatus()); + } + +} diff --git a/src/main/java/com/noplanb/global/payload/exception/NotFoundException.java b/src/main/java/com/noplanb/global/payload/exception/NotFoundException.java new file mode 100644 index 0000000..5cf45a7 --- /dev/null +++ b/src/main/java/com/noplanb/global/payload/exception/NotFoundException.java @@ -0,0 +1,13 @@ +package com.noplanb.global.payload.exception; + +import com.noplanb.global.payload.ErrorCode; + +public class NotFoundException extends BusinessBaseException { + public NotFoundException(ErrorCode errorCode) { + super(errorCode.getMessage(), errorCode); + } + + public NotFoundException() { + super(ErrorCode.NOT_FOUND); + } +}