2014년 5월 10일 토요일

4장 예외

4.1.2 예외의 종류와 특징

- Error : 애플리케이션 코드에서 catch할 수 없는 에러. 예를 들면, OutOfMemoryError, ThreadDeath.
- 체크예외 : 명시적인 처리가 필요한 예외. catch나 throw를 처리하지 않으면 컴파일에러가 발생한다.
- 언체크예외 : RuntimeException 클래스를 상속한 예외. 명시적인 예외처리를 강제하지 않기 때문에 언체크 예외라 불린다.

4.1.3 예외처리 방법

예외 복구
사용자에게 예외상황을 알리고 다른 방법을 안내해서 예외상황을 해결. 예를 들어, 네트워크가 불안해서 서버접속이 안되는 경우, 재시도를 통해서 예외를 복구할 수 있다.

예외처리 회피
throw를 통한 예외를 넘기는 행위. 근데 DAO단에서 catch한 뒤 throw를 하지 않은 상황에서 예외를 복구할 수 없는 경우는 어떻게 처리하지??? 결국 transaction을 처리하는 Controller단에서 rollback을 처리해야 하는 것 아닌가?

예외 전환
일반적으로 체크 예외를 계속 throws를 사용해 넘기는 건 무의미하다. 어차피 복구가 불가능한 예외라면 가능한 한 빨리 런타임 예외로 포장해 던지게 해서 다른 계층의 메서드를 작성할 때 불필요한 throws 선언이 들어가지 않도록 해줘야 한다.

대부분 서버환경에서는 애플리케이션 코드에서 처리하지 않고 전달된 예외들을 일괄적으로 다룰 수 있는 기능을 제공한다. 어차피 복구하지 못할 예외라면 애플리케이션코드에서는 런타임 예외로 포장해서 던져버리고, 예외처리 서비스 등을 이용해 자세한 로그를 남기고, 관리자에게는 메일 등으로 통보해주고, 사용자에게는 친절한 안내 메시지를 보여주는 식으로 처리하는 게 바람직히다.

4.1.4 예외처리 전략

런타임 예외의 보편화
예외처리를 강제하는 것은 예외가 발생할 가능성이 있는 API메서드를 사용하는 개발자의 실수를 방지하기 위한 배려라고 볼 수도 있겠지만, 실제로는 예외를 제대로 다루고 싶지 않을 만큼 짜증나게 만드는 원인이 되기도 한다.

자바가 처음 만들어질 때 많이 사용되던 애플릿이나 AWT, 스윙을 사용한 독립형 애플리케이션에서는 통제 불가능한 시스템 예외라고 할지라도 애플리케이션의 작업이 중단되지 않게 해주고 상황을 복구해야 했다. 예를 들어 워드의 파일 열기 기능에서 사용자가 입력한 이름에 해당하는 파일을 찾을 수 없다고 애플리케이션이 종료돼버리게 할 수는 없다.

하지만 자바 엔터프라이즈 서버환경은 다르다. 수많은 사용자가 동시에 요청을 보내고 각 요청이 독립적인 작업으로 취급된다. 하나의 요청을 처리하는 중에 예외가 발생하면 해당 작업만 중단시키면 그만이다. 독립형 애플리케이션과 달리 서버의 특정 계층에서 예외가 발생했을 때 작업을 일시 중지하고 사용자와 바로 커뮤니케이션하면서 예외상황을 복구할 수 있는 방법이 없다.

자바의 환경이 서버로 이동하면서 체크 예외의 활용도와 가치는 점점 떨어지고 있다. 자칫하면 throws Exception으로 점철된 아무런 의미도 없는 메서드들을 낳을 뿐이다. 그래서 대응이 불가능한 체크 예외라면 빨리 런타임 예외로 전환해서 던지는 게 낫다.

 public class DuplicateUserIdException extends RuntimeException {

  public DuplicateUserIdException(Throwable cause) {
   super(cause);
  }
 }

 public void add() throws DuplicateUserIdException{
  try{
   // JDBC를 이용해 user 정보를 DB에 추가하는 코드 또는
   // 그런 기능이 있는 다른 SQLException을 던지는 메서드를 호출하는 코드
  }catch(SQLException e){
   if(e.getErrorCode() == MysqlErrorNumbers.ER_DUP_ENTRY)
    throw new DuplicateUserIdException(e); //예외 전환
   else throw new RuntimeException(e);   //예외 포장
  }
 }

댓글 없음 :

댓글 쓰기