스터디/클린코드 노마드 북클럽

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

1005ptr 2024. 7. 3. 02:30
반응형

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

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

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

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

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

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

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

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

예외에 의미를 제공하라

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

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

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

정상 흐름을 정의하라

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

null을 반환하지 마라

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

null을 전달하지 마라

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

결론

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