구체적인 예외처리 없이는 에러 원인 파악도 사용성도 기대할 수 없다

레거시 유지보수 업무 중 있었던 일이다.

사용자가 화면에서 잘못된 날짜 값을 입력하고 업로드를 실행했다. Java 로직에서 그 날짜 값으로 쿼리를 날렸는데, 당연히 조회 결과가 없었다. 그 상태에서 .get()으로 null에 접근하려다 Null Pointer Exception이 터졌다.

CoreMap outMap = traExpFndMapper.selectOneTraExpFnd(inParam);
 
inParam.put("negoSeq", outMap.get("negoSeq")); // null인 outMap에 접근 → NPE

문제는 에러 메시지였다. 사용자 화면에는 그냥 NPE가 떴다. 사용자 입장에서는 뭐가 잘못됐는지 알 수가 없다. 개발자 입장에서도 해당 데이터를 직접 들고 디버깅해봐야만 원인을 알 수 있는 상황이었다.

뒤늦게 깨달은 건 처음부터 이 쿼리에 null 검사를 넣어야 했다는 것이다. 결과가 없을 때는 NPE가 아닌 비즈니스 예외로 처리하고, 사용자가 이해할 수 있는 메시지를 던져줬어야 했다.

CoreMap outMap = traExpFndMapper.selectOneTraExpFnd(inParam);
 
if (outMap == null) {
    throw new BusinessException(MessageUtil.getMessage("error.noTradeRecord"));
}
 
inParam.put("negoSeq", outMap.get("negoSeq"));

NPE는 JVM이 던지는 기술적 예외다. 사용자도, 로그를 처음 보는 개발자도 이 에러만으로는 “뭘 잘못했는지”를 알 수 없다. 반면 비즈니스 예외는 도메인 맥락을 담고 있다. “해당 거래 건을 찾을 수 없습니다”라는 메시지 하나가 디버깅 시간을 몇 배로 줄여준다.

예외처리를 어떻게 하느냐는 단순히 코드의 방어성 문제가 아니다. 애플리케이션이 실제로 쓰기 좋은 도구가 되느냐, 장애가 났을 때 빠르게 원인을 찾을 수 있느냐의 문제다.

연결 (이유)

출처(참고문헌)