TIL_220710_예외처리

창고·2022년 7월 11일
0

1. 예외 처리

(1) 글로벌 예외 처리

  • controller@ExceptionHandler 및 메소드 생성
    @ResponseStatus(value = HttpStatus.CONFLICT) // statusCode 200이 아닌 400번대로 내려줌
    @ExceptionHandler(IMakerException.class) // () 안에 Exception 종류 기입
    public IMakerErrorResponse handleException (IMakerException e,
                                                HttpServletRequest request) {
        log.error("errorCode : {}, url : {}, message : {}",
                e.getIMakerErrorCode(), request.getRequestURI(),
                e.getDetailMessage());

        return IMakerErrorResponse.builder()
                .errorCode(e.getIMakerErrorCode())
                .errorMessage((e.getDetailMessage()))
                .build();
    }
  • dtoResponse 클래스 생성
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class IMakerErrorResponse {
    private IMakerErrorCode errorCode;
    private String errorMessage;

}
  • [테스트] 결과

  • 단, StatusCode를 강제로 400번대로 맞추는 경우는 그닥 없음 (요즘 추세는)
    200으로 출력시키더라도 ErrorCodeErrorMessage로 상세 내용을 전달하는 편

  • 위의 방법은 controller마다 ExceptionHandler를 추가해줘야 하기 때문에
    controller가 많아지면 비효율적임

(2) 글로벌 예외 처리 추가

  • 좀 더 Global 하게 예외 처리 > exception 내에 ExceptionHandler 클래스 제작
@RestControllerAdvice // 각 controller에 조언(advice)를 해주는 class
@Slf4j
public class IMakerExceptionHandler {

    @ExceptionHandler(IMakerException.class) // () 안에 Exception 종류 기입
    public IMakerErrorResponse handleException (IMakerException e,
                                                HttpServletRequest request) {
        log.error("errorCode : {}, url : {}, message : {}",
                e.getIMakerErrorCode(), request.getRequestURI(),
                e.getDetailMessage());

        return IMakerErrorResponse.builder()
                .errorCode(e.getIMakerErrorCode())
                .errorMessage((e.getDetailMessage()))
                .build();
    }
  • request, validation 관련 exception 처리
    @ExceptionHandler(value = { // request, validation 관련 예외
            HttpRequestMethodNotSupportedException.class,
            // request에 대한 method가 일치하지 않는 경우
            // (postmaping method 주소에 put을 요청한다던지)
            MethodArgumentNotValidException.class
            // validation 진행 시 요구 사항에 맞지 않는 데이터가 들어올 경우
    })
    public IMakerErrorResponse handleBadRequest (Exception e,
                                                 HttpServletRequest request) {
        log.error("errorCode : {}, url : {}, message : {}", request.getRequestURI());

        return IMakerErrorResponse.builder()
                .errorCode(INVAILD_REQUEST)
                .errorMessage(INVAILD_REQUEST.getMessage())
                .build();
    }
  • 그 외 알 수 없는 exception 처리
    @ExceptionHandler(Exception.class) // 기타 예외
    public IMakerErrorResponse handleException (Exception e,
                                                 HttpServletRequest request) {
        log.error("errorCode : {}, url : {}, message : {}", request.getRequestURI());

        return IMakerErrorResponse.builder()
                .errorCode(INTERNAL_SERVER_ERROR)
                .errorMessage(INTERNAL_SERVER_ERROR.getMessage())
                .build();
    }
  • controller 에서는 데이터를 잘 받아왔는지 체크 / 정리하거나
    트랜잭션을 구분/분리해주는 최소의 역할 정도를 하는 것이 바람직함
profile
공부했던 내용들을 모아둔 창고입니다.

0개의 댓글