본문 바로가기
JAVA/[JAVA] 바구니

[JAVA] 예외 처리

by oncerun 2021. 3. 27.
반응형

 

자바를 배울 때 예외를 도대체 어떻게 처리를 하는 것이 올바른 것인지 모르고 단순히 다음과 같은 코드로 처리했다. 사실 실무에서도 종종 볼 수 있는 코드이다.

 

1. 예외를 잡아 놓고는 아무것도 하지 않는다.

try{
}catch(SQLException e){
}

2. 콘솔 출력

try{
}catch(SQLException e){
	System.out.println(e);
}

개발 중에는 콘솔 창에 메시지가 눈에 띄게 보이니 문제가 없지만 운영 서버에 올라가면 누가 콘솔 로그를 모니터링을 하나?

 

3. 빨간색 콘솔 출력

try{
}catch(SQLException e){
	e.printStackTrace();
}

난 모니터링 안 해

 

 

이러한 행동은 예외를 처리한 것이 아닌 방치한 것이다.

예외를 처리할 때 모든 예외는 적절하게 복구되든지 아니면 작업을 중단시키고 운영자 또는 개발자에게 분명하게 통보되어야 한다.

 

만약 예외를 잡아서 조치를 할 수 있는 방법이 존재하지 않다면? 모르겠다면 그냥 throws로 던져버리고 호출한 코드에 책임을 전가시켜라.

 

 

docs.oracle.com/javase/7/docs/api/java/lang/Error.html

 

Error (Java Platform SE 7 )

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because mos

docs.oracle.com

Error 클래스의 서브클래스들이 던지는 예외가 존재한다.

다음과 같이 알려진 서브클래스 종류가 존재한다.

AnnotationFormatError, AssertionError, AWTError, CoderMalfunctionError, FactoryConfigurationError, FactoryConfigurationError, IOError, LinkageError, ServiceConfigurationError, ThreadDeath, TransformerFactoryConfigurationError, VirtualMachineError

 

잘 읽어보면 애플리케이션단에서 예외를 잡아 처리할 수 없는 에러들이다. 자바 VM에서 관련된 에러들이다. 따라서 시스템 레벨에서 작업을 하는 것이 아니라면 애플리케이션에서는 신경 쓰지 않아도 된다.

 

docs.oracle.com/javase/7/docs/api/java/lang/Exception.html

 

Exception (Java Platform SE 7 )

protected Exception(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) Constructs a new exception with the specified detail message, cause, suppression enabled or disabled, and writable stack trace enabled or disabl

docs.oracle.com

이 예외들은 Error와 다르게 개발자가 만든 코드의 작업 중의 예외상황이 발생한 경우 사용된다.

철자 오류나, 클래스 찾지 못하거나, 널값이... 존재하거나 등등

 

이 Exception도 런타임 예외를 상속한 것을 언체크 예외라 하고 나머지를 체크 예외라고 한다.

보통 체크 예외를 잡지 않으면 컴파일 단계에서 에러가 발생하기 때문에 throws로 예외를 던져주거나 catch로 잡아서 처리해주어야 한다. 예를 들어 IOException, SQLException 등이 있다. 

 

런타임 예외를 상속한 예외들은 명시적인 예외처리를 강제하지 않기 때문에 언체크 예외라고 불리는데 이것들은 주로 프로그램의 오류가 있을 때 발생하도록 의도된 것이다. 즉 개발자가 부주의해서 발생할 수 있는 예외이기 때문이다.

 

그럼 개발자 입장에서는 체크 예외를 잡아야 맞는 것인데 자바 언어를 설계하고 JDK를 개발한 사람들은 언체크 예외만을 잡도록 만들었기 때문에 문제가 발생하기에 체크는 막무가내로 던지고 대충 처리하고 체크 예외가 발생하면 지점을 찾으러 개발자가 가야 하는 것이다.

 

애플리케이션 코드상에서 발생하는 예외 중 복구나 처리를 할 수 없는 경우는 어떻게 해야 할 까?

 

보통 체크 예외들은 catch문이나 throws를 강제하기 때문에 던지고 던지다 끝까지 던져버리는 경우가 있다.

이런 경우는 보통 런타임 익셉션을 상속받은 예외로 감싸서 처리하게 된다.

혹은 해당 예외를 받고 좀 더 의미 있는 예외를 던지도록 예외 이름 정도를 변경해 줄 수 있다.

 

복구할 수 없는 예외는 가능한 한 빨리 런타임 예외로 전환하여 처리하는 것이 바람직한다. 

 

예를 들어 JDBC의 SQLException 같은 경우는 체크 예외로 반드시 처리를 해야 하는 예외이다. 하지만 DB의 커넥션 풀이 가득 찼거나, 서버와의 연결이 끊어졌다면 애플리케이션 상에서 코드로 처리할 수 있는 방법이 없다. 이 경우에는 런타임 예외로 포장하여 던져야 한다. 발생을 관리자에게 메일로 통보해주고 사용자에게는 메시지를 전달해 주는 수밖에 없다.

 

하지만 재시도 정도는 해볼 수 있기 때문에 try/catch에서 예외를 잡고 다시 재시도를 해보는 것도 좋은 방법이다.

 

이러한 예외들은 보통 스프링에서는 추상화된 런타임 예외 계층을 제공해주기 때문에 좀 더 잘 포장된 예외처리를 해줄 수 있다. 

반응형

'JAVA > [JAVA] 바구니' 카테고리의 다른 글

[JAVA] Stream  (0) 2021.04.19
[JAVA] 디자인 패턴  (0) 2021.04.13
Java의 기본 log : Logger  (0) 2021.02.26
[JAVA] Java Virtual Machine  (0) 2020.07.08
[JAVA] RuntimeException  (0) 2020.06.06

댓글