예외 처리 문법의 목적은 오류가 발생한 지점과 처리하는 지점을 떼어 놓는 것이다. 그래서 잘 처리한다는 건 try-catch를 많이 쓰는 게 아니라 잘 던지고, 사용자에게 대응할 수 있는 경계에서 한 번에 잡는 것이다.
- 오류 코드 대신 예외(Replace Error Code with Exception):
return -23같은 오류 코드는 호출자마다 검사하고 위로 전달해야 한다. 예외는 핸들러를 찾을 때까지 스스로 콜 스택(Call Stack)을 거슬러 올라가므로 나머지 코드는 오류 상황을 신경 쓰지 않아도 된다 - 예외는 정말 예외일 때만: 프로그램의 정상 흐름에 속하는 경우에는 쓰지 않는다. 판단법은 "이 throw를 프로그램 종료로 바꿔도 정상 동작하는가"를 따져 보는 것이다
- 미리 검사할 수 있으면 검사로(Replace Exception with Precheck): 배열 범위 밖 접근을 catch해서 0을 돌려주기보다 호출 전에 범위를 확인한다
- 던지고 경계에서 잡는다: 대부분의 함수는 UI(User Interface)에서 멀다. 그 자리에서 할 수 있는 일이 없으니 그냥 던지고, 컨트롤러나 전역 핸들러에서 잡아 동작을 멈추고 사용자에게 알리고 기록한다. 스프링은 스프링 전역 예외 처리, React는 에러 바운더리(Error Boundary)가 그 경계다
- 폼 검증처럼 예상 가능한 실패는 검증 도구에 맡긴다(Bean Validation)
잡아 놓고 아무것도 안 하는 것은 가장 나쁜 선택이다(예외 삼키기). 파이썬의 "묻기보다 용서를 구하라(Easier to Ask for Forgiveness than Permission, EAFP)"와 "뛰기 전에 살펴라(Look Before You Leap, LBYL)" 사이의 선택은 EAFP와 LBYL에, 내부 가정 위반을 알리는 방법은 어서션에 있다.
출처: 『리팩터링 2판』 마틴 파울러 (원서 Refactoring, 2nd Edition) · refactoring.com: Replace Error Code with Exception · refactoring.com: Replace Exception with Precheck · Refactoring.Guru: Replace Error Code with Exception · 인프런 『심플 디자인』 박영록