[Java] Exception 분류 및 처리방법

GuruneLee·2022년 1월 12일
0

Let's Study 공부해요~

목록 보기
10/36

관련 포스트: 220111 CustomException 리팩토링

Java 의 Exception 에 관하여

예외와 오류

예외(Exception): 입력 값에 대한 처리가 불가능하거나, 프로그램 실행 중에 참조된 값이 자못된 경우 등 프로그램의 흐름에 어긋나게 하는 상황 (로직에서 발생한 실수 혹은 사용자의 영향)
오류(Error): 시스템에 뭔가 비정상적인 상황이 발생한 경우. 주로 JVM 이 발생시키는 것이며 이는 애플리케이션 코드에서 잡으려고 해도 방법이 없다. (시스템이 종료되어야 하는 수습할 수 없는 상황) OutOfMemoryError ThreadDeath StackOvefflowError 등이 있다.

오류와 에러의 상속 관계

CheckedException 과 UncheckedException

자바 예외 (+오류)

이 둘을 나누는 기준은 꼭 처리해야 하느냐이다.
CheckedException 이 발생할 가능성이 있는 로직은 반드시 복구, 회피, 처리 해줘야 하지만, UncheckedException 은 명시적인 예외처리를 하지 않아도 된다 (피할 수 있지만, 개발자가 부주의해서 발생하는 경우가 대부분이며 미리 예측할 수 있는 상황에서 발생하는 예외이르모 굳이 로직으로 처리를 할 필요가 없다) .

UncheckedException

RuntimeException 을 상속받는 모든 예외.
컴파일 시점에 예외를 catch 하는지 확인하지 않는다 => 컴파일 시점에 예외가 발생하는지 여부를 판단할 수 없다.
트랜잭션 Rollback 이 된다 (잘 와닿지 않는다).
예외가 발생하는 메서드에서 throws 예약어를 활용해 예외를 처리할 필요가 없다.

CheckedException

RuntimeException 을 상속받지 않는 모든 예외.
Compile Exception 이라고도 한다. 말 그대로 컴파일시점에 예외를 catch 하는지 정적으로 확인한다.
만약 컴파일 시점에서 예외에 대한 처리가 안되어있다면 with try/catch 컴파일 에러가 발생한다. 처리를 하지 않았다면 예외가 발생하는 메서드에서 throws 예약어를 활용해서 던져야 한다 (잘 와닿지 않는다).
트랜잭션 Rollback 이 안된다 (잘 와닿지 않는다).

예외 처리 방법

1. 예외 복구
: 예외가 발생해도 앱이 정상적으로 동작하게 한다.
ex. 네트워크 요청 실패시 재시도

static int MAX_RETRY = 10;

int retry = MAX_RETRY;
while (retry > 0) {
	retry -= 1;
	try{
    	...시도...
        ...성공 시 리턴...
    } catch(SomeException e) {
    	// 로그 출력
        // 실패 로직 존재 시 원상 복구
        // 일정 시간 대기
    } finally {
    	// 리소스 반납 및 정리
    }
}
// MAX_RETRY 초과 시 예외 Throw
throw new MAXTRYEXCEPTION();

2. 예외 처리 회피
: 예외가 발생하면 throws 를 통해 호출한쪽으로 던지고 자신의 책임을 없앤다.

// 예시 1
public void add() throws SQLException {
    // ...생략
}

// 예시 2 
public void add() throws SQLException {
    try {
        // ... 생략
    } catch(SQLException e) {
        // 로그를 출력하고 다시 날린다!
        throw e;
    }
}

3. 예외 전환
: 호출한 쪽에 던지는데, 더 명확하게 인지할 수 있도록 돕는 방법.

// 조금 더 명확한 예외로 던진다.
public void add(User user) throws DuplicateUserIdException, SQLException {
    try {
        // ...생략
    } catch(SQLException e) {
        if(e.getErrorCode() == MysqlErrorNumbers.ER_DUP_ENTRY) {
            throw DuplicateUserIdException();
        }
        else throw e;
    }
}

ref
https://velog.io/@gillog/Java-Exception-Handling복구-회피-전환
https://toneyparky.tistory.com/40
https://madplay.github.io/post/java-checked-unchecked-exceptions

profile
Today, I Shoveled AGAIN....

0개의 댓글