요즘 스프링 공부하는게 너무 재밌다.

처음에 이해가 가지않았을 때는 이게 뭔가 싶기도하고,,
학습의지가 떨어졌는데 어느 순간 깨달음을 얻고 나서는
다음 학습이 기대되고 얼른 더 다른걸 해보고 싶다.

어제는 클라이언트에서 받은 데이터를 예외처리하는
여러가지 방법을 알아보았다.

오늘은 예외 던지기에 대해 공부해 보는 날이다.
















어제는 @Vaild, @Vaildated 유효설 실패에 대한
예외처리를 하는 프로그램을 공부 했다.
오늘은 다른 예외들의 예외처리하는 프로그램을 공부해 보자.

1). 예외처리를 매개변수로 받기

@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorResponse handleResourceNotFoundException(RuntimeException error){
    System.out.println(error.getMessage());
    return null;
}

@ExceptionHandler로 에러를 감지하게 해주고
에러가 감지되었는데 RuntimeException에러가 발생하면
RuntimeException 클래스로 객체를 받아서
에러의 정보들을 객체를 통해 확인할 수 있다.

여기서 getMessage(); 메서드는
Throwalbe의 메서드를 상속받아 사용하고 있다.

throw new RuntimeException("Not found");

만약 다른 메서드에서 위와 같이 강제로 RuntimeException을 발생시키고
Message로 “Not found”라고 적어두었을 경우.
생성자로 RuntimeException의 String 값을 넣을 경우
최상위 클래스인 Throwable의 message가 저장되게된다.

해당 메서드가 실행 되면, @ExceptionHandler에 의해
RuntimeException 객체가 매개변수를 통해 전달된다.

문제점은 위의 예외상황은 RuntimeException만 작성했을 뿐
의도적으로 발생 시킬 예외 상황이 더 있을 수 있다.
그리고 예외 의도가 명확하지 않다는 점.


2). 개선된 예외 상황 처리

public enum ExceptionCode {
    MEMBER_NOT_FOUND(404, "Member Not Found");
    @Getter
    private int status;

    @Getter
    private String message;

    ExceptionCode(int status, String message){
        this.status = status;
        this.message = message;
    }
}
public class BusinessLogicException extends RuntimeException {
    @Getter
    private ExceptionCode exceptionCode;
    public BusinessLogicException(ExceptionCode exceptionCode){
        super(exceptionCode.getMessage());
        this.exceptionCode = exceptionCode;
    }
}
@ExceptionHandler
public ResponseEntity handleResourceNotFoundException(BusinessLogicException e){
    System.out.println(e.getExceptionCode().getStatus());
    System.out.println(e.getMessage());
    return new ResponseEntity(HttpStatus.valueOf(e.getExceptionCode().getStatus()));
}

위에 클래스를 3가지로 나누어서
BusinessLogicException 클래스를 통해
객체를 받는 방법이다.

먼저 enum 클래스를 통해서
사용할 생성자의 데이터를 맵핑해주고

BusinessLogicException 클래스를 만들어
RuntimeException을 상속해 spuer(); 생성자를 통해
Throawble까지 메세지를 올려주고, 객체를 저장하게 작성했다.
해당 객체는 @Getter를 이용해 가져올 수 있고
그 객체를 통해서 Enum의 Status값과 Message를 가져오는 모습이다.


throw new BusinessLogicException(ExceptionCode.MEMBER_NOT_FOUND);

최종적으로 예외를 강제로 위와 같이
MEMBER_NOT_FOUND로 던졌을 경우

BusinessLogicException 클래스와 ExceptionCode 클래스를
이용해 객체츨 만들고 예외처리로 흐름을 넘겨
우리가 커스터 마이징한 값을 출력하는 것 까지 보았다.

그럼 우리가 이제 이 기반으로
응답하는 객체를 새로 정리해서 보낸다든지?
커스터마이징이 가능하게 되는 것이다.

중요한 점은 에러가 강제로 발생 되었을 경우
우리가 흐름을 가져와 제어할 수있다는 점을 얻어간 것 같다.


어제 공부했던거와 더불어 다시 정리해보자면

  1. MethodArgumentNotValidException
    ->@Vaild 유효성 검증 실패한 예외잡기

  2. ConstraintViolationException
    ->@Vaildated 유효성 검증 실패한 예외잡기

  3. HttpRequestMethodNotSupportedException
    -> 해당 핸들러 메서드에 정의된 메서드와 호출한 메서드가 잘못되었을때 예외잡기

  4. NullPointerException : NullPoint 예외처리 발생한 것 잡기

  5. RuntimeException 클래스를 상속받아 클래스를 만들어
    제어흐름을 가져올 수 있음.


오늘의 커피량: ☕️ ☕️ ☕️
오늘의 점심: 라면, 불고기, 밥