지난 번에 다니던 회사에서는..
경우에 따라(라고 쓰고 매번이라 읽어야 한다) 다른 사람들이 만들어 놓은 소스를 수정해야 할 필요가 있었다.
보통 프로젝트를 진행한 사람들은 따로 있고, 이 사람들이 일을 대충 해 놓고 사라지면 그 일을 마무리 하거나 버그를 수정해야 하는 건 모조리 내 몫이었기 때문이다.
대개 이런 경우 - 일이 하기 싫었는지, 아니면 시간이 턱없이 부족했는지, 그것도 아니면 애초에 실력이 부족한건지, 아니면 그 모든 이유가 복합적으로 작용했든지..
상식적으로 이해하기 어려운 코드들이 작성된 경우가 많았다.

그 중에서도 특히 잦은 것은, 예외처리가 되어 있지 않은 경우였다.
다수의 메소드가 하나의 프로세스를 이룰 때, 어느 하나에서 오류가 나는데도 그냥 프로그램은 흘러간다거나..
아니면 아예 별다른 처리를 하지 않아 Internal Server Error를 뿌리거나 하는 등 말이다.

서비스 중인 프로그램이 오류가 나는 경우, 애초에 내가 작성한 코드들이 아니다보니 오류의 원인을 찾기란 무척 어렵다.
프로세스를 하나하나 짚어 가며, 해당 프로세스에 엮여 있는 클래스며 메소드들을 하나씩 짚어 가며 오류를 찾는데..
일정 규모 이상의 프로젝트에서는 이게 보통 일이 아니다.
실제 소스 수정에 들어가는 시간이 1분인데, 이를 위해 한 시간 내내 오류의 원인을 찾아야 할 때도 부지기수다.

굳이 이런 기억들을 꺼내지 않더라도, 프로그램을 개발할 때 예외처리가 중요하다는 것은 두 말 할 나위가 없다.
하지만 다른 모든 것들이 그렇듯, 세상에 몰라서 못 하는 일은 별로 없다.
알아도 못 하는 일들이 많은 것이 문제일 뿐이다.
프로젝트를 진행하면서 개발하는 수많은 코드들에 대해 일일히 예외처리를 꼼꼼히 한다는게 쉬운 일은 아니기 때문이다.
(물론 저 위에서 말한 것처럼 아예 안 되어 있기도 어렵다. 저건 아예 프로그래머로서 기본이 안 된 문제다.)

서두가 좀 길었지만.. 아무튼 이 장에서는 올바른 예외처리란 무엇인가를 이야기 하고 있다.

책에서는 예외처리에 대해 이야기를 하기 전에, 자바 시스템에서 예외란 무엇이고 어떤 것들이 있는지를 설명한다.
이는 자바에 대한 이론적인 내용으로 이 학습정리노트에서 자세한 내용을 언급할 필요는 없어 보인다.
간단히 정리하면 예외란 체크예외언체크예외(런타임예외)가 있고, 체크예외는 자바 문법 상 무조건 예외처리를 해야 한다.
우리가 코드 개발 시 만나는 일반적인 예외들은 대부분 체크예외다.

보통 프로젝트를 진행할 때 자주 사용되는 예외처리를 하는 방법은 다음과 같다.

1. 메소드를 try{}catch{}로 감싼 후 에러메시지를 시스템 로그에 찍는 방법.
2. 메소드 선언부에 throw Exception 으로 예외를 던지는 방법.

하지만 이것은 그야말로 예외처리를 위한 예외처리일 뿐인 경우가 많다.

catch된 예외를 제대로 처리해 주지 않고 그냥 시스템 로그에 찍기만 하는 경우에는 오류가 났는데도 다음 프로세스로 이동해 버리는 문제가 있기 때문에 주의를 기울이지 않으면 상황이 심각해진 후에야 오류를 파악할 수 있기 때문이다. 또 메소드 선언부에서 예외를 던지도록 해 놓은 경우 예외를 받아 들이는 상위 메소드에서는 오류가 있었다는 사실 외 어떤 오류가 났다는 것을 파악하기가 몹시 어려운 문제가 있다. 이 역시 예외처리를 위한 예외처리일 뿐 예외상황에 대한 대비로는 적절치 않다.

저자는 예외 처리를 위해(특히 체크 예외에 대해) 다음과 같은 전략을 제시한다. (4장의 정리 내용 중 일부 발췌)

 
  • 예외를 잡아서 아무런 조취를 취하지 않거나, 의미없는 throws 선언을 남발하는 것은 위험하다.
  • 예외는 복구하거나 예외처리 오브젝트로 의도적으로 전달하거나 적절한 예외로 전환해야 한다.
  • 좀 더 의미있는 예외로 변경하거나, 불필요한 catch/throws를 피하기 위해 런타임 예외로 포장하는 두가지 방법의 예외 전환이 있다.
  • 복구할 수 없는 예외는 가능한 한 빨리 런타임 예외로 전환하는 것이 바람직하다. //포기하면 편하다.
  • 애플리케이션의 로직을 담기 위한 예외는 체크예외로 만든다. //로직 상에서의 문제는 복구가 가능하거나, 최소한 이런 이런 오류가 있다는 것을 관리자/개발자에게 알리고 사용자에게 양해를 구하는 메시지를 전달하는 정도의 예외처리는 반드시 있어야 한다는 것이다.
  • JDBC의 SQLException은 대부분 복구할 수 없는 예외이므로 런타임 예외로 포장해야 한다. //쿼리문이 틀렸거나, 기타 다른 이유로 DB를 사용할 수 없을 때 이를 어플리케이션 단에서 스스로 예외를 복구한다는 것은 애초에 불가능하기 때문이다.
  • SQLException의 에러 코드는 DB에 종속되기 때문에 DB에 독립적인 예외로 전환될 필요가 있다. //이를 위해 아래서 얘기하는 DataAccessException이 필요하다.
  • 스프링은 DataAccessException을 통해 DB에 독립적으로 적용 가능한 추상화된 런타임 예외 계층을 제공한다. //이번 장에서는 이 내용에 대해 대충 훑어보는 정도로 넘어 갔다. 11장에서 다시 자세히 설명한다고 한다.
  • DAO를 데이터 엑세스 기술에서 독립시키려면 인터페이스 도입과 런타임 예외 전환, 기술에 독립적인 추상화된 예외로 전환이 필요하다. //간단히 말해 인터페이스로 구현해 스프링에서 DI를 관리할 수 있도록 하라는 뜻이다.


그 외 이 장에서 사용된 소스 코드 예제 등에 대해서는 별도로 언급할 필요가 없을 것 같다.

Posted by Kunner

댓글을 달아 주세요