Backend
home
🧹

6. chap07 - 오류 처리

생성일
2025/02/14 05:33
태그
CleanCode

1. 예외 처리 방식

오류 코드를 리턴하지 말고, 예외를 던져라
옛날에는 오류를 나타낼 때 에러코드를 던졌다.
하지만 예외를 던지는 것이 명확하고, 처리 흐름이 깔끔해진다.
예외를 던지고 처리하는 방식
오류가 발생한 부분에서 예외를 던진다.
별도의 처리가 필요한 예외라면 checked exception으로 던진다.
checked exception에 대한 예외처리를 하지 않는다면 메서드 선언부에 throws를 명시해야 한다.
예외를 처리할 수 있는 곳에서 catch하여 처리한다.

2. Unchecked Exception을 사용하라

Exception 가계도
Checked vs Unchecked Exception
Exception을 상속하면 Checked Exception 의 명시적인 예외처리가 필요하다.
ex) IOException, SQLException
RuntimeException을 상속하면 UncheckedException 의 명시적인 예외처리가 필요하지 않다.
ex) NullPointerException, illegalArgumentException, IndexOutOfBoundException
[Effective Java] Exception에 관한 규약
자바 언어 명세가 요구하는 것은 아니지만, 업계에 널리 퍼진 규약으로 Error 클래스를 상속하여 하위 클래스를 만드는 일은 자제한다. 즉, 사용자가 직접 구현하는 unchecked throwable은 모두 RuntimeException의 하위 클래스여야 한다.
Exception, RuntimeException, Error를 상속하지 않는 throwable을 만들 수도 있지만, 이러한 throwable은 정상적인 사항보다 나을 게 하나도 없기 때문에 API 사용자를 헷갈리게 할 뿐 절대로 사용하지 않는다.
Checked Exception이 나쁜 이유
특정 메소드에서 checked exception을 throw 하고 상위 메소드에서 그 exception을 catch 한다면 모든 중간단계 메소드에 exception을 throw 해야 한다.
OCP(개방-폐쇄 원칙) 위배 - 상위 레벨 메소드에서 하위 레벨 메소드의 디테일에 대해 알아야 하기 때문에 OCP 원칙에 위배된다.
필요한 경우 checked exception을 사용해야 되지만 일반적인 경우 득보다 실이 많다.
Unchecked Exception 을 사용하자
안정적인 소프트웨어를 제작하는 요소로 확인된 예외가 반드시 필요하지 않다는 사실이 분명해졌다. C#은 확인된 예외를 지원하지 않는다. 영웅적인 시도에도 불구하고 C++ 역시 확인된 예외를 지원하지 않는다. 파이썬이나 루비도 마찬가지다. 그럼에도 불구하고 C#, C++, 파이썬, 루비는 안정적인 소프트웨어를 구현하기에 무리가 없다.

3. Exception 잘 쓰기

예외에 메세지를 담아라
예외에 의미있는 정보 담기
오류가 발생한 원인과 위치를 찾기 쉽도록, 예외를 던질 때는 전후 상황을 충분히 덧붙인다.
실패한 연산 이름과 유형 등 정보를 담아 예외를 던진다.
exception wrapper
예외를 감싸는 클래스를 만든다
port.open()시 발생하는 checked exception들을 감싸도록 port를 가지는 LocalPort 클래스를 만든다.
port.open()이 던지는 checked exception들을 하나의 PortDeviceFailure exception으로 감싸서 던진다.

4. 실무 예외 처리 패턴

getOrElse

예외 대신 기본값을 리턴한다.
null 이 아닌 기본값
도메인에 맞는 기본값
1.
null이 아닌 기본값을 리턴한다
2.
도메인에 맞는 기본값을 가져온다

getOrElseThrow

1.
null 체크 지옥에서 벗어나자
2.
기본값이 없을 때는 null 대신 예외를 던진다
3.
파라미터의 null을 점검하라
실무에서는 보통 자신의 예외를 정의한다
에러 로그에서 stacktrace 해봤을 때 우리가 발생시킨 예외라는 것을 바로 인지할 수 있다.
다른 라이브러리에서 발생한 에러와 섞이지 않는다. 우리도 illegalArgumentException을 던지는 것보다 우리 예외로 던지는 게 어느 부분에서 에러가 났는지 파악하기에 용이하다.
우리 시스템에서 발생한 에러의 종류를 나열할 수 있다.

5. 오픈소스 속 Exception 살펴보기

apps-android-commons

parameter인 bookmark가 null이면 예외를 던지지 않고 false를 리턴한다.
bookmark 존재여부에 대한 메서드의 목적에 부합한다.
db 리소스를 처리할 때 checked exception인 RemoteException을 별도로 처리하지 않고 RuntimeException으로 바꿔서 던졌다.
finally 블록에서 리소스를 close 처리한다(리소스를 사용했다면 반드시 finally 블록에서 닫아줘야 한다).

Elastic Search