sami355 2023. 11. 2. 16:02

4.1 사라진 SQLException

  • 예외를 catch 했다고 해도 다시 밖으로 예외를 던져줘야 한다.
try {
    ...
}
catch(SQLException e){
    // 예외를 잡고는 아무것도 하지 않는다. 예외 발생을 무시해버리고 정상적인 상황인 것처럼
    //다음 라인으로 넘어가겠다는 분명한 의도가 있는 게 아니라면 연습 중에도 절대 만들어서는 안되는 코드이다.
}
  • 만약 catch를 하고 다시 던져주지 않으면 시스템 오류나 이상한 결과의 원인이 무엇인지 찾아내기가 매우 힘들다
  • System.out.println(e)이나 e.printStackTrace()를 통해 메시지를 출력하는 것은 다음과 같은 문제가 존재한다.
    1. 다른 로그나 메시지에 금방 묻혀버려 놓칠수 있다.
    2. 출력을 하는 것은 예외를 처리하는 것이 아니다.
  • 모든 예외는 적절하게 복구되든지 작업을 중단시키고 운영자 또는 개발자에게 분명하게 통보돼야 한다.
  • 예외를 잡아서 조치를 취할 방법이 없다면 잡지 말아야 한다.
  • 메서드 밖으로 throws Exception하는 것 역시 다음과 같은 문제점이 존재한다.
    • 정말로 예외적인 상황이 발생할 수 있다는 것인지 알 수 없다.
    • 적절한 처리를 통해 복구될 수 있는 예외상황도 제대로 다루지 못한다.

  • 예외는 다음과 나눌수 있다.
    1. Error
      1. 주로 VM에서 다루는 예외이다. 어플리케이션 단에서 신경쓰지 않아도 된다.
    2. checkedException
      1. RuntimException을 상속하지 않은 예외들로 만약 checkedException이 발생할 가능성이 존재한다면 throws혹은 catch문을 추가해줘야 한다. → 예외 처리 코드가 남용될 수 있다는 단점이 존재
    3. unCheckedException
      1. RuntimeException을 상속한 클래스로 프로그램의 오류가 있을 때 발생하도록 의도된 것이다.

  • 예외처리를 하는 방법은 다음과 같다.
    1. 예외 복구
      1. 예외로 인해 기본 작업 흐름이 불가능하면 다른 작업 흐름으로 자연스럽게 유도해주는 것이다.
    2. 예외상황을 파악하고 문제를 해결해서 정상 상태로 돌려놓는 것이다.
    3. 예외 처리 회피
      1. 예외처리를 회피하려면 반드시 다른 오브젝트나 메소드가 예외를 대신 처리할 수 있도록 해야 한다.
      2. 예외를 회피하는 것은 예외를 복구하는 것 처럼 의도가 분명해야 한다.
    4. 예외처리를 자신이 담당하지 않고 자신을 호출한 쪽으로 던져버리는 것
    5. 예외 전환
      1. 예외를 전환할때 DAO메소드에서 기술에 독립적이며 의미가 분명한 예외로 전환해서 던져줘야 한다.
      2. ex) SQLExceptionDuplicateUserIdException
      3. 전환하는 예외에 원래 발생한 예외를 담아서 중첩 예외(Nest Exception)로 만드는 것이 좋다.
      4. 중첩 예외는 새로운 예외를 만들면서 생성자나 initCause() 메소드로 근본 원인이 되는 예외를 넣어주면 된다.
      5. 예외처리를 강제하는 체크 예외를 언체크 예외인 런타임 예외로 바꾸는 경우에 사용한다.→ 언체크 예외로 던질 경우 throws 혹은 try-catch문을 작성하지 않아도 된다.
      6. → 대응이 불가능한 체크 예외라면 가능한 빨리 언체크 예외로 변경하면 좋다
    6. 발생한 예외를 그대로 넘기는 게 아니라 적절한 예외로 전환해서 던진다
  • 어디서든 checkedException을 다룰수 있다면 런타인 예외로 만드는게 낫다
  • 애플리케이션 자체의 로직에 의해 의도적으로 발생시키고, 반드시 catch 해서 무엇인가 조치를 취하도록 요구하는 예외도 있다. → 애플리케이션 예외라고 한다.
  • 애플리케이션 예외를 설계하는 방법은 두 가지가 존재한다.
    1. 다른 종류의 리턴 값을 돌려주는 것이다.
      1. 리턴 값을 명확하게 하지 않으면 혼란이 생길수 있다는 단점이 존재한다
      2. 리턴 값에 따라 로직이 변경되므로 if문이 남발될 수 있다.
    2. 예외상황에서 비즈니스적인 의미를 띈 예외를 던지도록 만든다.

➕ 만약 예외 발생시 RunTimeException을 상속받은 사용자 정의 예외를 던지고 @ControllerAdvice@ExceptionHandler로 관리하면 깔끔하게 코드 관리 할 수 있다.