ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 4장) 4.1 예외
    Java & Spring/토비의 스프링 3.1 2021. 6. 17. 17:11
    반응형

    4장 예외

    4.1 사라진 SQLException

    • 스프링의 JdbcTemplate을 적용하면서 throws SQLException 선언이 적용 후에 사라졌다.

    • 초난감 예외처리

      • 예외가 발생하면 catch 블록을 써서 잡는 것은 좋지만 아무 것도 하지 않고 넘어가는 것은 위험
        • 프로그램 실행 중 어디에서 오류가 있는지 모른채 무시하고 계속 진행하기 때문
        • 조치를 취할 방법이 없다면 잡지 말고 throws를 메소드 밖으로 던지고 자신을 호출한 코드에 예외처리 책임을 전가하는 것이 차라리 낫다
      • 실행 창에 로그나 메시지로 남기는 경우 다른 수많은 로그나 메시지에 금방 묻힘
      • 예외 처리 시, 반드시 지켜야할 핵심 원칙
        • 복구되든지 작업을 중단시키고 운영자 or 개발자에게 분명하게 통보돼야함
    • 무의미하고 무책임한 throws

      • 모든 예외를 무조건 던져버리는 선언에는 심각한 문제점이 존재
        • 의미 있는 정보를 얻을 수 없고, 적절한 처리를 통해 복구될 수 있는 예외 상황을 다룰 기회를 박탈당함
      • 예외를 무시하는 방법이나, 무책임한 throws는 절대 지양해야함
    • 예외의 종류와 특징

      • 자바의 예외 3가지
        • Error, Exception, RuntimeException
        • Error
          • 시스템에서 비정상적인 상황이 발생한 경우
          • 주로 자바 VM에서 발생, Application 코드에서 잡으려고 하면 안됨
        • Exception(CheckedException)
          • 애플리케이션 코드의 작업 중 예외 상황이 발생한 경우 사용
          • Exception에는 Checked와 UnChecked가 존재
          • CheckedException은 Exception의 서브 클래스면서 RuntimeException 클래스를 상속받지 않은 예외들
          • 예외를 어떤 식으로든 복구할 가능성이 있는 경우 사용
        • RuntimeException(UncheckedException)
          • RuntimeException을 상속한 클래스들
          • 명시적인 예외처리 강제 X
          • catch로 잡거나 throws 하지 않아도 됨
            • 명시적으로 throws 선언해줘도 되지만, 무의미
          • 프로그램의 오류가 있을 때 발생하도록 의도된 것들
          • 피할 수 있지만 부주의로 발생할 수 있는 경우를 위한 예외
    • 예외처리 방법

      • 전략
        • 예외 복구
          • 예외상황을 파악 ~> 문제 해결 ~> 정상 상태로 작동
          • 예외로 인해 기본작업 흐름이 불가능하다면 다른 작업 흐름으로 유도
          • 예를 들면, DB 서버에 접속할 때, 횟수에 제한을 두고 연결 재시도를 할 수 있음
        • 예외처리 회피
          • 자신을 호출한 곳으로 throws 하거나 catch and throw(주로 로그 남기고 다시 던짐)
          • JdbcTemplate으로 예를 들면, 콜백 오브젝트 메소드에서 SQLException을 템플릿으로 던짐
            • SQLException을 처리하는 일이 콜백 오브젝트의 역할이 아니기 때문
          • 자신의 역할이 아닌 경우 throws 하지만, 역할 분담을 제대로 하고 있지 않고 무책임한 throws는 무책임한 회피
          • 위의 경우처럼 의도가 명확해야함
        • 예외 전환
          • 예외를 복구해서 정상적으로 만들 수 없기 때문에 예외를 적절한 예외로 처리하여 메소드 밖으로 던짐
          • 목적
            • 의미를 분명하게 해줄 수 있는 예외로 바꿔주기 위해
              • 서비스 계층 오브젝트가 적절한 복구 작업을 시도 가능
              • 전환 예외에 원래 발생한 예외를 담어 중첩 예외(Nested Exception)으로 처리
              • 새로운 예외를 만들면서 생성자나 initCause() 메소드로 원인을 넣어줌
            • 예외를 포장
              • 새로운 예외를 만들고 원인이 되는 예외를 내부에 담아서 던지는 방식은 같음
              • 의미를 명확하게 하려는 목적이 아니라는 점이 다름
              • 주로 Checked Exception을 Runtime Exception으로 전환하는 경우에 사용
              • 의미 있는 예외거나 복구 가능한 예외가 아니라면 런타임 예외인 EJBException으로 포장해서 던지는 편이 좋음
                • EJBException은 시스템 익셉션으로 인식하고 트랜잭션을 자동으로 롤백
              • 애플리케이션 코드에서 로직상의 예외인 경우는 의도적으로 Checked Exception을 던지는 것이 좋음
    • 예외처리 전략

      • 런타임 예외의 보편화
        • Checked Exception가 일반 예외, UnChecked는 시스템 장애나 프로그램 오류에 사용
        • JavaEE에서는 서버 특정 계층에서 예외가 발생했을 때, 작업을 일시 중지하고 사용자와 바로 커뮤니케이션하면서 예외상황을 복구할 수 있는 방법이 없음
        • 예외상황을 미리 파악하고 예외가 발생하지 않도록 차단하는 것이 좋음
        • 대응이 불가능한 체크 예외는 런타임 예외로 전환해서 던지는게 좋음
      • add() 메소드의 예외 처리
        • ID 중복의 경우 좀 더 의미 있는 예외인 DuplicatedUserIdException으로 전환해주고, 아니라면 SQLException을 그대로 던지는 예시를 구현
          • SQLException은 복구 불가능하고 처리할 것이 없음
            • 런타임 예외로 포장해서 메소드 밖으로 던져서 처리
          • DuplicatedUserIdException을 잡아서 처리할 수 있다면 런타임 예외로 만드는 것이 좋음
        • RuntimeException으로 처리하는 경우 예외 상황에 대한 충분한 고려가 필요
      • 애플리케이션 예외
        • 애플리케이션 자체 로직에서 의도적으로 발생해서 catch로 조치를 취하도록 요구하는 예외
        • 예시
          • 은행 계좌에서 출금하는 기능의 메소드
            1. 예외 경우에 따라 각기 다른 종류의 리턴 값을 돌려주고, 메소드를 호출한 쪽에서 리턴 값을 확인
              ~> 리턴 값을 명확하게 코드화하고 잘 관리하지 않으면 복잡한 상황 발생
              ~> 조건문이 자주 등장해서 코드가 지저분해지고 흐름 파악이 어려움
            2. 예외 상황에서 비즈니스적 의미를 띤 예외를 던짐
              의도적으로 체크 예외를 만들어서 개발자가 잊지 않고 예외 상황에 대한 로직을 구현하도록 강제
              ~> 예외 정보를 함께 넣어 적절한 대응을 하도록 관리
    • SQLException은 어떻게 됐나?

      • SQLException은 코드 레벨에서 복구할 수 있는 예외가 아님
        • 예외가 발생했다는 사실을 빠르게 전달하는 것이 중요
        • 예외처리 전략을 적용해서 기계적인 throws를 지양
        • 빠르게 UncheckedException(RuntimeException)으로 전환하는 것이 좋음
    반응형

    댓글

Designed by Tistory.