본문 바로가기

Homo Coding

런타임 계열 예외와 checked 예외

자바에서 예외(Exception)은 크게 checked 예외와 unchecked 예외로 나뉘어진다. checked 예외는 코드에서 명시적으로 try-catch-finally 예외 처리를 해야하는 것을 의미하며, unchecked 예외는 그럴 필요가 없는 것을 의미한다. checked 예외에서 try-catch로 예외를 처리하지 않는 경우에는 메소드에 throws 절을 추가해야 한다.

자바에서 checked 예외는 java.lang.Exception 을 상속받는 형태이며, unchecked 예외는 java.lang.RuntimeException을 상속받는 예외이다. checked 예외이든 unchecked 예외이든 두가지 모두 동일한 기능을 수행한다. 따라서, 어느 것이 더 낫다라고 말할 수는 없다. 하지만, 예외 발생시 어떠한 로직을 추가하느냐에 따라서 그 비용적인 측면은 다양할 수 있다.

 또한, 트랜잭션, 원격 호출과 같은 지점에서 주로 런타임 계열의 unchecked 예외를 사용하는 것이 일반적이며, 이는 기반 기술 (JEE, Spring)들이 런타임 계열의 예외에 대해 자동으로 트랜잭션 처리를 해주고 있다. (Spring에서는 checked 예외에 대해서는 트랜잭션 처리가 가능하지만, 관행과 같이 런타임 계열을 사용하는 방식을 권고한다.)

비즈니스 예외의 경우, 내부적으로 특정 예외를 지정하여 사용할 때에는 checked 예외를 사용하기도 하지만, 런타임 계열의 예외를 사용하는 것이 추가 코드가 들어가지 않고, try-catch로 별도 로직을 구성하지 않는 이상 checked 예외를 사용하는 것은 여러가지로 고려해서 신중할 필요가 있다. 보통 예외를 먹는다는 표현과 같이 try-catch 구문 안에서 checked 예외를 처리하고 catch 절에서 아무런 행위를 하지 않으면, 예외 발싱시 문제점을 추적하기가 쉽지 않다.

try {
   // some business logic
} catch (SomeCheckedException e) {
   e.printStackTrace();
   // do nothing



위의 코드가 대표적으로 예외를 먹는 행위이다. 물론, 예외 처리를 하지 않는 명확한 이유가 있고, 그 안에서 대부분의 예외를 처리한다고 하면, 이와 같은 코드는 크게 상관은 없을 수도 있겠지만, 일반적으로 보아서, 예외를 catch하고 이를 호출하는 측에 아무런 반응을 알리지 않는다면 좋지 않은 코드가 될 가능성이 높다.

또한, 예외를 예외로 받지 않고, 예외 발생시 다양한 코드를 받게끔 처리하는 경우도 있는데, 이러한 경우 예외에 대한 모든 경우들을 검토해야 한다. (마치 HTTP로 통신시 예외에 대한 코드를 정의하듯이 예외코드와 정확한 의미를 상세하게 정의해야 한다.)

이러한 다양한 경우들을 처리하는 것에 대한 부담이 있고, 어떻게 처리할지를 잘 모르겠다면 시스템 내부에서의 예외는 가능하다면 모두 Runtime 계열로 처리하고, UI 접점에서 이러한 예외들을 처리하게끔 하는 것이 가장 나은 방법인 것 같다. UI에서 이러한 다양한 예외들을 어떻게 보여줄 것인지에 대한 고민은 사용자의 요구사항을 들을 필요가 있지만, 대부분이 그냥 시스템에 문제가 있다라는 형태의 오류만을 보기를 원할 것이다. 사실 예외 메시지에 대한 대부분은 개발자들이 보고 싶은 데이터이지 사용자에게 의미있는 정보들은 아니다. (물론, 입력 폼 처리에서 어떠한 정보가 누락되었는지 정합성이 문제가 되었는지는 가능하면 상세하게 보여줄 필요가 있지만, DB 오류 코드나, SQL 구문, 내부 시스템 네트워크 문제, 잘못된 코드 등을 사용자에게까지 보여줄 필요는 없을 것이다.)

결국, 예외는 개발/운영하는 사람들을 위해서 수집하도록 하면 되고, 문제 발생시 추적하여 해결할 수 있는 수준에서 예외 처리를 하면 된다. 즉, UI 접점 내의 서버에는 모든 예외가 런타임 계열로 정의하고(물론, 필요한 경우 checked 예외를 선언하여 처리하면 된다. 다만 이 경우는 세심한 주의가 필요할 뿐이다.), UI에서 발생되는 예외를 비동기로 분석하여 추후 문제 해결시 사용하면 된다. 예외는 전체 시스템 차원에서 처리하는 방식과 일정한 형식을 필요로 하며, 문제를 해결할 수 있는 수준에서 적당하게 사용하면 된다. 또한, 예외코드 사용시 상세한 내용을 문서화/명세화시켜서 남겨두어야 한다.