[Java] 예외 번역과 예외 연쇄 기법

2024. 9. 30. 16:28·JVM/Java

 

문제 상황

수행하려는 일과 관련 없는 예외가 튀어나오면 당황스럽다.

고수준 메소드가 저수준의 예외 처리하지 않고 바깥으로 전파해버릴 때 발생하는 문제다.

 

해결 방법

상위 계층 저수준 예외를 잡아 자신의 추상화 수준에 맞는 예외로 바꿔야한다.

 

try {
 // 저수준 예외 발생
 } catch (LowerLevelException e) {
   // 추상화 수준에 맞게 번역
   throw new HigherLevelException(...)
 }

왜, 언제 사용하는가?

저 수준의 예외가 디버깅에 도움이 될 때다.

 

 

예외 번역 (Exception Translation)

class AbstractSquentialList {
	/*
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E get(int index) {
        try {
            return listIterator(index).next();
        } catch (NoSuchElementException exc) {
        	// 저수준의 NoSuchElement 상황을
            // 고수준 Exception 으로 '어느 index' 에서 에러가 났는지 감싼다.
            throw new IndexOutOfBoundsException("Index: "+index);
        }
    }

}

 

하위레벨 NoSuchElementException 의 Cause 를 숨기고

고수준의 Exception 정보만 노출시킨다.

"필요한 고수준 정보만 유저에게 노출한다" 가 핵심이다.

 

예외 연쇄 (Exception Chaining)

저수준의 근본 원인(Cause)를 고수준 예외에 실어 보내는 기법.,

try {
  // 저수준 추상화
} catch (LowerLevelException cause) {
  // 저수준 예외를 고수준에 실어 보냄
  throw new HigherLevelException(cause);
}

 

디버깅 해상도를 높이기 위해 고수준 Exception 에서 저수준 Exception Cause 를 실어 노출시킨다.

예외 연쇄는  "깊은 디버깅을 위해 저수준 에러 로그를 노출한다" 가 핵심이다.

 

HigherLevelException 에 메시지만 더하는 예외 번역 기법에서는 하위레벨 로그가 노출되지 않아 디버깅이 어려울 때가 있다.

이럴 때 예외 연쇄를 적용할 수 있다.

 

예외 번역 + 연쇄 조합 사용

둘의 장점을 조합한 기법이다.

대부분의 Java Exception 은 고수준에서 번역된 예외 메시지를 작성하고, 저수준 예외도 같이 실어 보낼 수 있다.

public class IllegalArgumentException extends RuntimeException {
 // ..
  public IllegalArgumentException(String message, Throwable cause) {
    super(message, cause);
  }
}

 

try {
  // 저수준 추상화
} catch (LowerLevelException cause) {
  // 에러 메시지를 번역하고 + 저수준 예외를 고수준에 실어 보냄
  throw new HigherLevelException("Higher level exception", cause);
}

요약

구분 Exception Translation Exception Chaining
저수준 Cause 유지 여부 X O
Debugging 상세 수준 고수준 저수준
사용 목적 필요한 정보만 고수준의 예외로 노출
저수준 Exception 을 은닉
상세한 디버깅을 위한 원본 Cause 노출

 

저작자표시 (새창열림)

'JVM > Java' 카테고리의 다른 글

[Java] 람다 캡쳐와 Synthetic 람다 클래스  (0) 2025.02.19
[Java] OutOfMemory 잡기  (0) 2025.01.28
[Java] Thread 상속 대신 Runnable 을 사용하라.  (0) 2024.07.21
[Java] Guava - MultiMap , BiMap  (0) 2024.07.14
[Java] Generic vs WildCard  (2) 2024.01.07
'JVM/Java' 카테고리의 다른 글
  • [Java] 람다 캡쳐와 Synthetic 람다 클래스
  • [Java] OutOfMemory 잡기
  • [Java] Thread 상속 대신 Runnable 을 사용하라.
  • [Java] Guava - MultiMap , BiMap
M_Falcon
M_Falcon
  • M_Falcon
    Falcon
    M_Falcon
  • 전체
    오늘
    어제
    • 분류 전체보기 (432)
      • Web (16)
        • Nodejs (14)
        • Javascript (23)
        • FrontEnd (4)
      • DataBase (39)
        • Fundamental (1)
        • Redis (4)
        • PostgreSQL (10)
        • NoSQL (4)
        • MySQL (9)
        • MSSQL (3)
        • Error (4)
      • Algorithm (79)
        • Algorithm (문제풀이) (56)
        • Algorithm (이론) (23)
      • JVM (65)
        • Spring (13)
        • JPA (5)
        • Kotlin (13)
        • Java (24)
        • Error (7)
      • 기타 (70)
        • Kafka (3)
        • Kubernetes (3)
        • Docker (13)
        • git (19)
        • 잡동사니 (27)
      • 재테크 (11)
        • 세무 (4)
        • 투자 (3)
        • 보험 (0)
      • BlockChain (2)
        • BitCoin (0)
      • C (32)
        • C (10)
        • C++ (17)
        • Error (3)
      • Low Level (8)
        • OS (3)
        • 시스템 보안 (5)
      • 네트워크 (3)
      • LINUX (30)
        • Linux (26)
        • Error (4)
      • 저작권과 스마트폰의 이해 (0)
      • 생각 뭉치 (6)
      • 궁금증 (2)
      • Private (4)
        • 이직 경험 (0)
        • 꿈을 찾아서 (1)
      • Android (21)
        • OS (4)
  • 블로그 메뉴

    • 홈
    • WEB
    • 알고리즘
    • DataBase
    • Linux
    • Mobile
    • C
    • 방명록
  • 링크

    • github
  • 공지사항

  • 인기 글

  • 태그

    C++
    docker
    프로그래머스
    linux
    Spring
    java
    PostgreSQL
    Kotlin
    ubuntu
    JPA
    Git
    javascript
    database
    algorithm
    알고리즘
    Bitcoin
    백준
    kafka
    android
    Programmers
  • hELLO· Designed By정상우.v4.10.3
M_Falcon
[Java] 예외 번역과 예외 연쇄 기법
상단으로

티스토리툴바