티스토리 뷰
최근 코드를 보다 보니 문득 드는 생각이 하나 있었다.
“왜 이렇게 Exception catch가 숨어있지?”
백엔드 코드를 짜다 보면, 서비스 로직이라는 게 있고, 그 외의 ‘도구적인 작업’들이 있다.
DB를 쓰거나, 외부 API를 호출하거나, 캐시를 쓰거나, 이벤트를 전송하는 그런 것들.
근데 문제는... 이런 도구적인 부분에서 너무 과도한 예외 처리를 해버린다는 거였다.
물론 의도는 좋았다. 장애가 안 나게 막으려는 거니까.
근데 이게 꼭 좋은 건 아니라는 생각이 들었다.
왜냐면 예외를 그 자리에서 catch하고, 자체적으로 fallback을 처리해버리면
그건 서비스 로직 바깥에서 서비스 로직을 대신 결정해버리는 셈이었으니까.
예를 들어보자.
DB 저장이 실패했을 때, 외부 API 호출이 실패했을 때
그 상황에서 “fallback으로 빈값을 반환한다”거나 “그냥 로그만 찍고 무시한다”는 결정은,
사실 도메인 관점에서 굉장히 중요한 로직이었다.
어떤 경우에는 진짜 API 실패로 이어져야 했고,
어떤 경우에는 “괜찮아, 다음 단계로 진행해도 돼”라고 판단해야 했다.
그 판단은 결국 서비스 로직의 몫이지, DB나 API 호출 함수 내부의 몫이 아니었다.
그래서 오히려 throw를 더 적극적으로 고민해야 한다고 봤다.
“여기서 뭘 막을까?”보다 “이 실패를 위로 올렸을 때 서비스가 뭘 해야 하지?”를 고민하는 게 맞다고 생각했다.
그게 올바른 서비스 설계라는 생각을 했다.
그런데 코드를 보면 Output port (Repository, API Client..)쪽에 catch가 너무 많았다.
마치 “예외는 절대 밖으로 보내선 안 돼!” 라고 느껴졌다.
근데 그건 기계적인 방어 코드일 뿐, 서비스의 의미를 담은 로직은 아니었다.
catch의 남발은 오히려 코드의 구조를 이해하기 흐리게 만드는 것 같았다.
더 나아가 Checked Exception도 한 번쯤은 생각해봐야 하지 않을까.
실패 가능성이 명확하고, 호출자가 그걸 반드시 처리해야 하는 경우라면.
하지만 또 이걸 너무 남용하면 오히려 코드가 복잡해지고, Checked Exception을 안티패턴처럼 보는 분위기도 있으니까
이건 조심스럽게 접근해야 했다.
결론적으로 하고싶은말은, 도구는 도구일 뿐이다.
DB, API, 캐시, 이벤트 - 이런 건 서비스 로직을 구현하기 위한 수단이었고,
그 실패를 어떻게 다룰지는 온전히 서비스의 결정이 되어야 했다.
그래서 catch를 줄이고, throw를 고민해야 한다.
예외는 막는 게 아니라, 의미 있게 다루어져야 한다.
'Development' 카테고리의 다른 글
| ORM은 레거시가 될까? (0) | 2025.12.27 |
|---|---|
| Next.js와 Supabase를 접고 다시 스프링으로 (0) | 2025.11.18 |
| MSA에서 헥사고널 아키텍처가 적절하지 않은 이유 (0) | 2025.07.01 |
| Next.js + Vercel 환경에서 한글 검색 구현 삽질기록 (0) | 2025.05.04 |
| WebRTC란 무엇인가? (0) | 2024.10.06 |