Spring - (26) : Exception

­이승환·2021년 12월 18일
0

spring

목록 보기
23/26

Overview


토비의 스프링을 보고 개인적으로 요약한 자료이다. 이번 포스팅에서는 예외에 관해서 적고자 한다.

문제가 있을 시, lshn1007@hanyang.ac.kr 로 메일주시면 삭제하겠습니다.

잘못된 예외처리

1. 예외를 잡고는 아무것도 하지 않을 때

* 예외 발생을 무시하고 다음 라인으로 넘어가겠다는 의도가 있는 것이 아니라면 절대 하면 안됨
* 예외 발생을 무시하고 넘어가면 특정 기능이 비정상 동작하거나, 메모리 또는 리소스가 낭비될 수 있음
* 디버그 하기 힘들어 질 수 있음

2. 예외를 잡고는 콘솔에 출력만 하는 행위

* 로그를 모니터링하지 않는 이상 무시될 수 있으므로 catch 블록을 이용해서 출력만 한것은 제대로 된 예외 처리를 한 것이 아님

3. 예외 처리의 책임을 전가만 하는 행위

* 사용하려는 메소드에서 어떤 문제가 발생할 수 있는 지 의미 있는 정보를 얻을 수 없음
public void method1() throws Exception {
	method2();
}

public void method2() throws Exception {
	method3();
}

public void method3() throws Exception {
	...
}

굉장히 부끄러운 챕터임... 실제로 2번과 같은 행위를 프로젝트에서 진행한 경험이 있음

예외의 종류와 특징

자바에서 throw를 통해 발생시킬 수 있는 예외는 총 3가지가 존재한다.

1. Error

  • 시스템 상에서 비정상적인 상황이 발생한 신호
  • JVM에서 발생시키는 것으로, 개발자가 모든 케이스에 대해 대응할 수 있는 방법이 없기 때문에 애플리케이션 상에서 해결하려고 하지 않아도 됨
  • 시스템 레벨에서 특별한 작업을 하는 게 아니라면 애플리케이션에서는 이러한 에러에 대한 처리는 신경쓰지 않아도 됨

2. Checked Exception

  • 개발자들이 만든 코드에서 예외 상황이 발생했을 경우에 사용
  • 체크 예외는 런타임 에러가 아닌 경우를 말하는 경우가 대부분
  • 체크 예외가 발생할 수 있는 메소드 사용의 경우, 예외처리 코드가 필수적임
  • IOException, SQLException 이 대표적인 예시임

3. UnChecked Exception

  • 명시적인 예외처리를 강제하지 않기 때문에 언체크 예외라 부름
  • 에러와 마찬가지로 런타임 예외는 catch문으로 잡거나 throws로 선언하지 않아도 됨
  • 런타임 예외는 주로 프로그램의 오류가 있을 때 발생하도록 의도된 것들임
  • 피할 수 있지만 개발자의 로직 실수나 부주의로 인해 발생할 수 있는 예외들로 구성
  • NullPointerException, IllegalArgumentException등이 대표적인 예시임

예외 처리 방법

1. 예외 복구

  • 예외 상황을 파악하고 문제를 해결해서 정상 상태로 돌려놓는다.
/**
 * 예시 : 네트워크가 불안정한 상태에서 원격 DB에 접속하던 중 예외가 발생한 경우에는 정해진 횟수만큼 재시도하여 복구
 */
int maxRetry = MAX_RETRY;

while (maxRetry-- > 0) {
	try {
		...			// 예외가 발생할 가능성이 있는 시도
		return;		// 작업 성공
	} catch (SomeException e) {
		// 로그 출력. 정해진 시간만큼 대기
	} finally {
		// 리소스 반납. 정리 작업
	}
}

throw new RetryFailedException();	// 최대 재시도 횟수를 넘기면 직접 예외 발생(복구가 불가능하므로 더 시도하지 않고 예외 복구 포기)

2. 예외 처리 회피

  • 예외 처리를 자신이 담당하지 않고, caller에게 전달하는 방법
// 예외 처리 회피 1 - throws
public void add() throws SQLException {
	// JDBC API
}

// 예외 처리 회피 2 - rethrow
public void add() throws SQLException {
	try {
		// JDBC API
	} catch (SQLException e) {
		// 로그 출력
		throw e;
	}
}

3. 예외 전환

  • 예외 처리와 마찬가지로 예외 처리의 책임을 호출한 쪽으로 전달하지만, 발생한 예외를 그대로 넘기지 않고 적절한 예외로 전환해서 전달하는 방법을 말함

  • 예외 전환은 두 가지 목적으로 사용된다.

    	(1) 발생한 예외를 그대로 던질 때 해당 예외 상황에 대한 적절한 의미를 부여하지 못하는 경우 의미를 분명히 하기 위해 사용
    	(2) 예외를 처리하기 쉽고 단순하게 만들기 위해 사용(ex. 체크 예외를 언체크 예외로 포장해 전달한다.) -> CheckedException 을 UnCheckedException으로 변경하는 로직
  • 발생한 예외의 의미를 분명히 하는 예제

public void getAll(User user) throws QuerySyntaxException, SQLException {
	try {
        ...
	} catch (SQLException e) {
		// 에러 코드가 ER_PARSE_ERROR 면 예외 전환
		if (e.getErrorCode() == MysqlErrorNumbers.ER_PARSE_ERROR) {
			throw new QuerySyntaxException();
		} else {
			throw e;
		}
	}
}

예외 처리 전략

1. 런타임 예외를 통한 예외 처리 전략

  • 애플리케이션 코드에서 발생할 수 있는 체크 예외를 런타임 예외로 전환해 처리하는 전략이다.
  • 이 전략을 사용하면 복구가 불가능한 체크 예외에서 의미 있는 예외만 런타임 예외로 전환해 처리할 수 있으며, 불필요한 throws문을 제거할 수 있다.
  • 하지만 런타임 예외로 만들었기 때문에 사용에 더 주의를 기울여야 한다. 컴파일러에서 예외 처리를 강제하지 않기 때문에 예외 상황을 충분히 고려하지 못할 가능성이 있기 때문이다. 따라서 런타임 예외를 사용하는 경우에는 API 문서나 레퍼런스 문서 등을 통해 메소드를 사용할 때 발생할 수 있는 예외의 종류와 원인, 활용 방법을 자세히 설명해두는 것이 좋다.
  • Spring에서 활용한다면, JPA나 JDBC 활용 중 DB Server Sql Exception에서 활용할 수 있을 것으로 보인다. 해당 예제는 추후 포스팅에서 설명될 예정이니 생략하도록 하겠다.

2. 애플리케이션 예외를 통한 예외 처리 전략

  • 비즈니스적인 의미를 가지는 예외를 체크 예외로 만들어 다른 계층에서 예외 처리를 강제하도록 하는 전략이다.
  • 애플리케이션 로직에 의해 의도적으로 발생시켜 반드시 catch를 통해 조치를 취하도록 요구하는 예외를 일반적으로 애플리케이션 예외라고 한다.
  • catch로 잡아주지 않는다면, 컴파일 타임에서 잡아낼 수 있다는게 큰 특징이다.
  • 일반적으로 이러한 예외는 의도적으로 체크 예외로 만드는데, 정상적인 흐름을 따르는 코드는 그대로 두고, 예외 상황에서는 비즈니스적인 의미를 띠는 예외를 던지도록 만드는 전략이다.
  • 이 전략을 이용하면 개발자가 예외 상황에 대한 로직을 구현하도록 강제할 수 있고, if문이 반복 사용되지 않게 만들 수 있어 코드의 가독성도 향상된다.
try {
	BigDecimal balance = account.withdraw(amount);
	...
} catch (InsufficientBalanceException e) {		// 체크 예외
	// 예외에 담긴 인출 가능한 잔고 금액 정보를 가져옴
	BigDecimal availFunds = e.getAvailFunds();
	...
}

예외처리의 격언

  • 예외를 회피하는 것은 예외를 복구하는 것처럼 의도가 분명해야 한다.
  • 모든 예외는 적절하게 복구되든지 아니면 작업을 중단시키고 운영자 또는 개발자에게 분명하게 통보돼야 한다.
  • 예외를 무시하거나 잡아먹어 버리는 코드는 만들지 말아야 하며, 굳이 예외를 잡아서 조치할 방법이 없다면 잡지 말아야 한다. (throw를 통해 예외 처리의 책임 을 전가 하든지...)
profile
Mechanical & Computer Science

0개의 댓글