본문 바로가기
스터디/클린코드 노마드 북클럽

북클럽 클린코드 7장. 오류 처리

by 1005ptr 2024. 7. 3.
반응형

오류 처리는 중요하지만 오류 처리 코드로 인해 프로그램 논리를 이해하기 어려워진다면 깨끗한 코드라 부르기 어렵다.

우아하고 고상하게 오류를 처리하는 기법과 고려사항 몇 가지를 알아보자.

오류 코드보다 예외를 사용하라

  • 오류 코드를 던지면 호출자가 즉시 오류를 처리해야 된다.
  • 예외를 던지면 호출자에서 처리할 수도 있고, 상단으로 넘길 수도 있다.
  • 예외를 던지면 정상 처리 흐름과 예외 처리 흐름이 분리돼서 코드가 깔끔해진다.

Try-Catch-Finally 문부터 작성하라

  • 예외가 발생할만한 코드를 짤떄는 일단 감싸자
  • 강제로 예외를 일으키는 테스트 케이스를 작성한 후 테스트를 통과하게 코드를 작성하는 방법을 권장한다.
  • 자연스럽게 try 블록의 트랜잭션 범위부터 구현하게 되므로 범위 내에서 트랜잭션 본질을 유지하기 쉬워진다.

미확인(unchecked) 예외를 사용하라

  • checked 예외의 장단점을 놓고 논쟁이 있었음
  • 메서드를 선언할 때 메서드가 반환할 예외를 모두 열거하는 것
  • 확인된 예외는 OCP(Open Closed Principle)를 위반한다.
    • 호출부가 모두 예외 선언부 변경에 영향을 받는다.
    • 오류를 원거리에서 처리하기 위해 예외를 사용한다는 사실을 감안한다면 이처럼 확인된 예외가 캡슐화를 깨버리는 현상은 유감스럽다.

예외에 의미를 제공하라

  • 전후 상황을 충분히 덧붙이자.
  • 오류가 발생한 원인과 위치를 찾기 쉬워진다.
  • 호출 스택만으로는 부족하다.
  • 실패한 연산 이름과 실패 유형

호출자를 고려해 예외 클래스를 정의하라

  • 오류가 발생한 위치로 분류
  • 오류가 발생한 컴포넌트로 분류
  • 오류의 유형으로 분류
    • 디바이스 실패, 네트워크 실패, 프로그래밍 오류 등
  • 오류를 정의할 때 프로그래머에게 가장 중요한 관심사는 오류를 잡아내는 방법이 되어야 한다.
  • 대다수 상황에서 오류를 처리하는 방식은 일정하다.
    • 오류를 기록한다.
    • 프로그램을 계속 수행해도 좋은지 확인한다.
  • 감싸기 기법을 쓰면 외부 API를 쓸 때 프로그램 과 의존성이 크게 줄어든다.
  • 감싸서 특정 API 처리는 감싸는 객체에 숨기고 프로그램이 처리할 API는 입맛에 맞게 고정시킬 수 있다.
  • 흔히 예외 클래스가 하나만 있어도 충분한 코드가 많다.
    • 예외 클래스에 포함된 정보로 오류를 구분해도 괜찮은 경우
    • 한 예외는 잡아내고 다른 예외는 무시해도 괜찮은 경우라면 여러 예외 클래스를 사용한다.

정상 흐름을 정의하라

  • 비즈니스 논리와 오류 처리가 분리되면
  • 코드 대부분이 깨끗하고 간결한 알고리즘으로 보이기 시작한다.
  • 그러다보면 오류 감지가 프로그램 언저리로 밀려난다.
  • 떄로는 중단이 적합하지 않은 때도 있다.
  • 예외를 위에서 처리하는 예시
    • 예외를 아래로 내려보내서 상황에 맞게 처리하여 값을 전달함
    • 이를 특수 사례 패턴(special case pattern)이라 부른다.
    • 클래스를 만들거나 객체를 조작해 특수 사례를 처리하는 방식이다.
    • 클라이언트 코드가 예외적인 상황을 처리할 필요가 없어진다.
    • 이미 다 처리돼서 넘어오기 때문에

null을 반환하지 마라

  • 널을 반환하면 널 익셉션이 가장 많이 발생하는 오류다.
  • 널체크 코드로 가득한 코드도 코드 가독성을 떨어뜨린다.
  • 널을 반환하는 코드는 호출자에게 일을 떠넘긴다.
  • 널을 던져야 하는 상황의 대안
    • 예외를 던지거나
    • 특수 사례 객체를 반환하자
  • 외부 API가 null을 반환한다면
    • 래퍼 메서드를 구현해 처리하자.
  • 많은 경우에 특수 사례 객체가 손쉬운 해결책이다.

null을 전달하지 마라

  • 널을 전달하는 방식은 더 나쁘다.
  • 인수에 널을 전달하는 코드는 최대한 피해야 한다.
  • 인수에 널을 전달해도 된다면?
    • 그 코드 자체도 좀 별로라고 생각한다.
  • 대다수 프로그래밍 언어는 호출자가 실수로 넘기는 null을 적절히 처리하는 방법이 없다.
  • 그렇기에 애초에 null을 넘기지 못하도록 금지하는 정책이 합리적이다.
  • 인수로 null이 넘어오면 일단 코드에 문제가 있다는 말이다. ==> 상황 판단이 단순해진다.

결론

  • 코드는 읽기도 좋아야 하지만 안정성도 높아야 한다.
반응형

댓글