7. 오류 처리
오류 코드보다 예외를 사용하라
오류 처리 코드와 호출하여 논리를 진행하는 코드가 섞이면 알아보기가 어렵다.
논리가 뒤섞여 있기 때문.
try/catch/finally 문부터 작성하라
try 블록에 들어가는 코드를 실행하면 어느 시점에서든 실행히 중단된 후 catch 블록으로 넘어갈 수 있다.
어떤 면에서 catch 블록은 트랜잭션과 비슷하다.
try 블록에서 무슨 일이 생기든 catch 블록은 프로그램 상태를 일관성 있게 유지해야 한다.
먼저 강제로 예외를 일으키는 테스트 케이스를 작성한 후 테스트를 통과하게 코드를 작성하는 방법을 권장한다.
미확인 예외를 사용하라
확인된 예외를 할 경우 최하위 (연쇄반응에서의 마지막) 함수에서 확인된 예외를 던질 경우
상위 함수에서는 그 예외를 알아야 하고, 결론적으로 캡슐화가 깨지게 되는 현상이 발생한다.
일반적인 애플리케이션은 의존성이라는 비용이 이익보다 크다.
예외에 의미를 제공하라
예외를 던질 때는 전후 상황을 충분히 덧붙인다.
그러면 오류가 발생한 원인과 위치를 찾기 쉬워진다. 즉, catch 문에 logger 등을 사용
호출자를 고려해 예외 클래스를 정의하라
애플리케이션에서 오류를 정의할 때 프로그래머에게 가장 중요한 관심사는 오류를 잡아내는 방법이 되어야 한다.
대다수 상황에서 우리가 오류를 처리하는 방식은 (오류를 일으킨 원인과 무관하게) 비교적 일정하다.
- 오류를 기록
- 프로그램을 계속 수행해도 좋은지..
외부 라이브러리를 사용할 경우 외부 라이브러리에서 나올 에러를 예외처리 하기보단 외부 라이브러리 자체를 예외 처리해라.
그래야 외존성도 좋고 갈아타는 비용도 적다
null 을 반환하지 마라
null 체크를 기반으로 돌아가는 코드는 엄밀히 말하자면 나쁜 코드다.
null 을 반환하는 코드는 일거리를 늘릴 뿐만 아니라 호출자에게 문제를 떠넘긴다.
누구 하나라도 null 체크를 빼먹는다면 애플리케이션이 통제 불능에 빠질지도 모른다.
매서드에서 null 을 반환하고픈 유혹이 든다면 그 대신에 예외를 던지거나 특수 사례 객체를 반환한다.
그리고 자바에선 Collections.emptyList() 가 있어 미리 정의된 읽기 전용 리스트를 반환한다.
null 을 전달하지 마라
메서드에 null 을 반환하는 방식도 나쁘지만, 메서드로 null 을 전달하는 방식은 더 나쁘다.
정상적인 인수로 null 을 받는 API 가 아니라면 null 을 넘기는 것은 최대한 지양해라.
대다수 프로그래밍 언어는 호출자가 실수로 null 을 넘겼을 때 적절히 처리하는 방법이 없다.
그렇다면 애초에 null 을 넘기지 못하게 하는 것이 합리적이다.
즉, 인수로 null 이 넘어오면 코드에 문제가 있다는 말이다.
결론
깨끗한 코드는 읽기 좋아야 하지만, 안정성도 높아야 한다. 그리고 이 둘은 상충하는 목표가 아니다.
오류 처리를 프로그램 논리와 분리하면 독립적인 추론이 가능해지며 코드 유지보수성도 높아진다.
사견을 덧붙이면…?
글쎄.. 배울 때부터 try-catch 문을 사용하도록 배워서 그런지, 오히려 오류 코드라는 게 더 생소했다.
null 에 관련해서는 에피소드가 떠오르는게 꽤 된다.
전 회사에서 코드 품질인증인지 뭔지를 받는다고 소스를 검증 업체에 넘긴 적이 있다.
거기서 많이 나왔던 지적 사항이 null 체크를 안한다는 것이었다. 그래서 당시에 엄청난 야근을 하면서(…) null 체크 로직을 넣곤 했다.
당시엔 뭣도 모르는 신입 시절이라 하라는대로 했지만, 지금 생각해보면 그런 체크를 일일히 넣어줬어야 했던 코드인가? 에 대해서는 좀 의문이 든다.
그리고 다른 에피소드는 비교적 최근 일인데,
본인이 작업한 소스를 보여주고, 어떻게 리팩토링을 진행했는지 발표하는 그런 리팩토링 스터디에 참가했었다.
그 자리에서 다른 발표자의 자료를 보고 있는데, 마침 눈에 들어 왔던게, null 을 파라미터로 넣고 진행하는 메소드가 눈에 보였다.
왜 null 을 넣었고, 무슨 의도였는지 물어볼까 하다가 시간이 지나서 결국은 못 물어봤던 기억이 있다. (아직까지 생각나는거보니 나는 그런 형태가 되게 싫었나보다.)
내성적이라 말할 타이밍을 놓치고 그냥 넘어가는 경우가 많은데, 이런 부분은 고쳐야 되겠다 싶다.