[토비의 스프링 3.1] 4주차 스터디 - 예외

리리·2025년 1월 24일
0

토비의 스프링

목록 보기
6/6

스터디 날짜 24.07.29.
스터디 범위 4장. 예외


4.1.2 예외의 종류와 특징

자바에서 throw를 통해 발생시킬 수 있는 예외

  1. Error

    1. 자바 VM에서 발생시키며, 애플리케이션 레벨에서 잡을 수 있는 예외가 아니다.
    2. ex) OutOfMemory, ThreadDeath
  2. Exception과 체크 예외

    1. 애플리케이션 코드 상에 예외사항이 발생했을 때 java.lang.Exception 클래스가 사용된다.

    2. Exception 클래스는 체크 예외와 언체크 예외로 구분된다.
      Untitled

    3. 일반적으로 예외는 체크 예외라고 생각하면 된다.

      → ex) IOException, SQLException

    4. 체크 예외가 발생할 수 있는 메서드를 사용할 때는 반드시 예외 처리 코드를 함께 작성해야 한다.

      → 체크 예외는 복구할 가능성이 조금이라도 있는, 예외사항을 다루기 때문.

  3. RuntimeException과 언체크/런타임 예외

    1. 명시적인 예외 처리를 강제하지 않으며, 프로그램 오류가 있을 때 발생되도록 의도된 것들이다.

      → ex) NULLPointerException, IllegalArgumentException

    2. 런타임 예외는 예상치 못했던 상황에서 발생하는 것이 아니고, 피할 수 있지만 개발자의 부주의에 의해 발생할 수 있는 예외를 다룬다.

→ 체크 예외는 예외 처리를 강제하는 것 때문에 예외 블랙홀이나 무책임한 throws 코드가 남발되어 비난의 대상이 되기도 했다.


4.1.3 예외처리 방법

예외를 처리하는 일반적인 방법

  1. 예외 복구

    • 예외상황을 파악하고 문제를 해결해서 정상 상태로 돌려놓는 것
    • 기본 작업 흐름이 불가능할 때 다른 작업 흐름으로 자연스럽게 유도해주는 경우 예외를 복구했다고 볼 수 있다.
  2. 예외처리 회피

    • 자신을 호출한 쪽으로 예외처리를 던져버린다.

    → thorws 문으로 선언 or catch 문으로 예외를 잡고 rethrow

    public void add() throws SQLException {
    	try {
    		//
    	} catch(SQLException e) {
    		// pring log
    		throw e;
    	}
    }
    • 예외를 회피하는 것은 예외를 복구하는 것처럼 의도가 분명해야 한다.
    • 콜백/탬플릿처럼 긴밀한 관계에 있는 다른 오브젝트에게 책임을 분명히 지게 하거나,
    • 자신을 사용하는 쪽에서 예외를 다루는 게 최선의 방법이라는 분명한 확신이 있어야 한다.
  3. 예외 전환

    • 예외 회피와 달리, 발생한 예외를 그대로 넘기는 것이 아니라 적절한 예외로 전환해서 던진다.
    • 의미를 분명하게 해줄 수 있는 예외로 바꿔줄 수 있다.
      • 중복 아이디 사용자를 등록하려고 할 때 SQLException → DuplicationUserIdException

        public void add(User user) thorws DuplicateUserIdException, SQLException {
        	try {
        		// DB에 User 추가
        	} catch(SQLException e) {
        		if (e.getErrorCode() == MysqlErrorNubmers.ER_DUP_ENTRY)
        			throw DuplicateUserIdException();
        		else
        			throw e;
        		}
        	}
    • 전환하는 예외에 원래 발생한 예외를 담아서 중첩예외로 만드는 것이 좋다.
      catch(SQLException e) {
      	throw DuplicateUserIdException(e);
      }
      
      catch(SQLException e) {
      	throw DuplicateUserIdException().initCause(e);
      }
      • 의미를 명확하게 하려고 예외 전환하는 것이 아니고, 예외처리를 강제하는 체크 예외를 언체크 예외인 런타임 예외로 바꾸는 경우에 사용한다.
      • 복구 불가능한 예외라면 가능한 한 빨리 런타임 예외로 포장해 던지게 해서 다른 계층의 메소드를 작성할 때 불필요한 thorws 선언이 들어가지 않도록 해줘야 한다.

4.1.4 예외처리 전략

런타임 예외의 보편화

  • 최근 등장하는 표준 스펙 또는 오픈소스 프레임워크에서는 API가 발생시키는 예외를 언체크 에외로 정의하는 것이 일반화되고 있다.
  • 대개 복구 불가능한 상황이고 RuntimeException 등으로 포장해서 던져야 할 테니 아예 API 차원에서 런타임 예외를 던지도록 만들어서 그 밖의 메소드들이 신경 쓰지 않게 해주는 편이 낫다는 것이다.
public class DuplicateUserIdException extends RuntimeException {
	public DuplicateUserIdException(Throwable cause) {
		super(cause);
	}
}

public void add() thorws DuplicateUserIdException {
	try {
		//
	} catch (SQLException e) {
		if (e.getErrorCode() == MysqlErrorNubmers.ER_DUP_ENTRY)
			throw new DuplicateUserIdException(e); //예외 전환
		else
			throw new RuntimeException(e); //예외 포장
	}
}

→ 낙관적인 예외처리 기법. 복구할 수 있는 예외는 없다고 가정하고 예외가 생겨도 런타임 예외이므로 시스템 레벨에서 처리하거나 꼭 필요한 경우는 런타임 예외를 잡아 복구하거나 대응해줄 수 있다는 태도를 기반으로 함.


애플리케이션 예외

  • 외부의 예외상황이 원인이 아니라 애플리케이션 자체의 로직에 의해 의도적으로 예외를 발생시키고, 반드시 catch해서 조치를 취하도록 요구하는 예외
  • ex) 잔고 부족 상황에서 출금처리를 하려고 할 때 → 비즈니스적인 의미를 띤 예외를 던지도록 하고, 체크 예외로 만들어 에외상황에 대한 로직을 구현하도록 강제한다.
    try {
    	BigDecimal balance = account.withdraw(amount);
    } catch(InsufficientBalanceException e) {
    	BigDecimal availFunds = e.getAvailFunds();
    	//잔고 부족 메시지를 준비하고 이를 출력하도록 진행
    }

4.2.2 DB 에러 코드 매핑을 통한 전환

DB 종류가 바뀌더라도 DAO를 수정하지 않으려면

아래의 두 가지 문제를 해결해야 한다.

  1. SQLException의 비표준 에러 코드

    if (e.getErrorCode() == MysqlErrorNumbers.ER_DUP_ENTRY) { ... 

    → DB별로 DB에러 코드가 다르기 때문에 DB 독립적인 코드가 될 수 없다.

  2. SQLException이 제공하는 SQL 상태 정보

    • Open Group의 XOPEN SQL 스펙에 정의된 상태코드
      • 통신장애로 DB연결에 실패한 경우 08S01
      • 테이블이 존재하지 않는 경우 42S02

    → DB의 JDBC드라이버에서 SQLException을 담을 상태 코드를 정확하게 만들어주지 않는 문제가 있다.


해결책은,

  • DB 업체별로 만들어 유지하고 있는 DB 전용 에러 코드를 사용해 예외의 원인이 무엇인지 해석해주는 기능을 만든다.
    • ex) 중복 오류가 발생하는 경우 MySQL-1062, Oracle-1 등의 에러 코드를 받게 되는데, 이 코드를 DuplicateKeyException이라는 의미가 분명히 드러나는 예외로 전환해준다.

0개의 댓글

관련 채용 정보