만두의 Exception?

2024. 8. 5. 00:29·Java
목차
  1. 표준 예외를 사용하자
  2. 예외 번역(exception translation) 하자
  3. 예외 메세지에 발생 원인 정보를 적자
  4. 예외를 무시하지 말자
  5. 글을 마치며

사진과 내용은 무관하다

 

 오늘의 주제는 Exception이다. 최근 공통 프로젝트에서 무지성 200 OK를 반환하는 바람에, 이제 슬슬 예외 처리에 대한 필요성을 느끼고 있다. 더 깔끔한 코드를 작성하기 위해서 이펙티브 자바를 읽으며 공부해 본 내용을 공유하겠다.

표준 예외를 사용하자

 표준 예외는 이미 많은 개발자들에게 익숙한 예외들이다. 그렇기 때문에 다른 개발자들이 읽기 쉽고 사용하기 쉬워진다. 또한 예외 클래스 수가 적어질수록 메모리 사용량과 클래스 적재 시간이 줄어든다. Java 라이브러리에서 대부분의 API를 커버할 수 있는 예외를 제공하기 때문에 표준 예외로도 충분하다.

 가장 자주 재사용하는 Exception 몇 가지를 소개해보겠다.

IllegalArgumentException 허용하지 않는 값이 parameter로 건네졌을 때
(null은 관례상 NullPointerException으로 처리한다.)
IllegalStateException 객체가 메서드를 수행하기에 적절하지 않은 상태일 때
NullPointerException null을 허용하지 않는 메서드에 null을 건넸을 때
IndexOutOfBoundsException 인덱스가 범위를 넘어섰을 때
ConcurrentModificationException 허용하지 않는 동시 수정이 발견됐을 때
UnsupportedOperationException 호출한 메서드를 지원하지 않을 때
ArithmeticException, NumberFormatException 산수나 수 변환에서 에러가 발생했을 때

 상황에 부합한다면 표준 예외를 사용하는 것이 좋다. 다만, API 문서를 읽고 Exception이 던져지는 상황에 대한 이해는 필수적이다.

 

예외 번역(exception translation) 하자

 호출한 메서드에서 발생한 Exception을 무턱대고 전파했던 기억이 있다. 그렇다면 그 예외는 결국 메서드가 하는 일과 전혀 관련없는 예외처럼 보여서 정확히 에러의 원인을 알기 힘들다. 이 문제를 해결하기 위해서 예외 번역을 사용하자.

 예외 번역은 상위 계층에서 저수준의 예외를 잡아서 자신의 추상화 수준에 맞는 예외로 바꿔던지는 것이다. 

try {
	// 저수준의 추상화 이용
	...
} catch (LowerLevelException e) {
	// 예외 번역
    throw new HigherLevelException();
}

 넓은 범위의 Exception을 좀 더 구체화해서 던지면 좋다는 의미이다. 예외를 계속해서 넘기는 것보다 의미를 구체화해서 다시 던져주는 게 더 좋지만, 아래 계층에 parameter 값을 전달하기 전에 검증해서 예외가 발생하지 않도록 하거나 현재 계층에서 Exception을 처리하고 logging 하는 것도 좋은 방법이다.

 

예외 메세지에 발생 원인 정보를 적자

 예외를 잡지 못해서 프로그램이 실패했을 때 자바 시스템에서는 stack trace 정보를 자동으로 출력하지만 경우에 따라서 Exception의 message만 볼 수 있을 때가 있다. 만약 예외 상황을 재현하지 못할 때는 얻을 수 있는 정보가 해당 message가 전부일 때가 있다.

 message에 예외가 터진 상황에 대한 정보를 담으려면 예외에 관여된 모든 매개변수와 필드의 값을 Exception message에 담아야 한다. 만약 특정 변수에 null이 담겨서 NullPointerException이 터졌다면 해당 변수명과 null이라는 정보를 담아주면 된다.

 다만,  Exception message와 최종 사용자에게 보여줄 오류 메시지는 별개이다. 최종 사용자에게는 가독성 좋은 메세지를 보여줘야 하고 Exception message는 Exception이 터지는 상황에 대한 정보를 담는 것이 가장 중요하다.

 

예외를 무시하지 말자

 메서드 선언에 Exception이 있다는 것은 해당 Exception에 대한 처리를 요구하는 것이다. 예외는 try-catch문으로 잡아버리면 그만이지만 catch문을 비워서는 안 된다. 

 가끔 Exception을 무시해야할 때도 있는데 그럴 때는 주석을 남기고 Exception 변수명을 ignored로 바꿔두자.

try {
    url = URLDecoder.decode(url, "UTF-8");
} catch (UnsupportedEncodingException ignored) {
	// UTF-8 사용
}

 

글을 마치며

 지금까지 Exception을 깔끔하게 사용하기 위한 내용들을 알아봤다. 굉장히 기본적인 내용들이지만 개발하다 보면 귀찮아서 자연스럽게 코드를 이상하게 적는다. 🥲

try {
} catch (Exception e) {
	e.printStackTrace();
}

 사소한 곳에서 오는 비용이 꽤 크다. 다른 팀원들과 협업하며 개발하면서 사소한 걸 놓치면 의사소통이 잘 되지 않는다는 걸 느끼기도 했고, 결국 코드가 더러워져서 리팩토링에도 큰 시간을 할애해야 한다. 기본적인 내용들을 지키며 개발하도록 노력해야겠다. 

'Java' 카테고리의 다른 글

븟츠의 clone 재정의는 항상 조심하자!  (0) 2024.08.25
자바 코딩 컨벤션 정리  (0) 2024.08.18
븟츠의 JWT 소개 및 정리  (0) 2024.08.03
븟츠의 try-finally 보다는 try-with-resources를 사용하자!  (0) 2024.07.28
만두의 불변객체(Immutable Object)와 record  (0) 2024.07.27
  1. 표준 예외를 사용하자
  2. 예외 번역(exception translation) 하자
  3. 예외 메세지에 발생 원인 정보를 적자
  4. 예외를 무시하지 말자
  5. 글을 마치며
'Java' 카테고리의 다른 글
  • 븟츠의 clone 재정의는 항상 조심하자!
  • 자바 코딩 컨벤션 정리
  • 븟츠의 JWT 소개 및 정리
  • 븟츠의 try-finally 보다는 try-with-resources를 사용하자!
월월월월2
월월월월2
백엔드로 살아남기 입니다.
월월월월2
백엔드로 살아남기
월월월월2
전체
오늘
어제
  • 분류 전체보기 (64)
    • Spring (15)
    • TroubleShooting (2)
    • Infra (7)
    • Java (9)
    • Docker (7)
    • Database (1)
    • Algorithm (9)
    • React (8)
    • CS (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

링크

공지사항

인기 글

태그

자바빈즈패턴
도커
countingsort
JPA
#security
Docker in Docker
springboot
낙관적 락
비관적 락
연관 관계
Spring Security
다중 usersdetail
react testing library
Java
트러블슈팅
application.properties
dind
DevOps
YAML
MSA
Docker
spring
23288
자바
스프링
스프링스케줄러
Algorithm
점층적생성자패턴
Docker Out of Docker
사가 패턴

최근 댓글

최근 글

hELLO· Designed By정상우.v4.6.1
월월월월2
만두의 Exception?

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.