Spring

[Spring] 체크예외 / 언체크 예외

개바리여리 2025. 6. 29. 22:12

체크 예외

컴파일 시점에 반드시 예외 처리를 강제하는 예외이다.

Exception을 상속하지만, RuntimeException은 제외한 예외들입니다.

복구 가능성이 있는 예외이므로 예외를 처리하는 코드를 함께 작성해야 합니다.

실제로 개발에서 발생하는 예외들은 복구 불가능 경우가 대다수이다.

 

SQLException 같은 체크 예외를 처리해도 쿼리를 수정하여 재배포 해야 적용이 가능하다.

 

특징:

  • 컴파일러가 try-catch나 throws로 예외 처리를 강제
  • 예외 처리를 하지 않으면 컴파일 에러 발생
public void readFile(String path) throws IOException {
    FileReader reader = new FileReader(path); // IOException은 체크 예외
}

 

IOException은 throws로 던지거나 try catch 로 처리해줘여 한다.

 

언체크 예외

컴파일러가 예외 처리를 강제하지 않는 예외이다.

RuntimeException과 그 하위 클래스들입니다.

대표적으로 NullPointerException  이나 IllegalArgumentException 등이 있다.

특징:

  • 예외 처리를 선택적으로 할 수 있음
  • 개발자가 잘못된 로직을 짰을 때 발생 (ex. NPE, IndexOutOfBounds 등)
  • 실행 중(Runtime) 에만 에러 발생

 

 

 

스프링에서는 주로 언체크예외 (RuntimeException) 을 주로 사용합니다.

서비스 로직에서 불필요한 try catch 남발을 방지하고 

트랜잭션 기본 롤백도 기본적으로 언체크 예외일 때만 동작합니다.

 

 

에러(Error)와 예외(Exception)는 다르다

에러는 메모리 부족 같은 시스템의 비정상적인 상황인 경우에 사용하는 것이다.

JVM에서 주로 발생하며 딱히 캐치해서 대응을 해줄 방법도 없다. 보통은 그래서 특별한 에러 처리를 안해준다.

 

 

예외 복구

예외를 파악하고 해결하여 정상 상태로 돌려놓는것.

 

ex : 네트워크 실패시 재시도

public String getDataFromServer() {
    try {
        return networkClient.request(); // 실패할 수 있음
    } catch (IOException e) {
        // 예외 복구: 디폴트 값 반환
        log.warn("서버 요청 실패. 기본값 반환");
        return "default-data";
    }
}

 

복구 전략

기본값 반환 예외 대신 미리 정한 안전한 값으로 대체
재시도 일정 횟수만큼 다시 시도 (네트워크, API 호출 등)
무시 예외 발생한 부분을 건너뛰고 나머지를 계속 수행
다른 로직 대체 실패한 작업을 유사한 방식으로 우회 처리
사용자 안내 UI에 “다시 시도해주세요” 등의 메시지 출력

 

 

예외 처리 회피

예외 처리를 직접 하지않고, 자신을 호출한 곳으로 던져버린다. (throws Exception)

근데 무분별한 예외 회피는 좋지 않으니 적절하게 사용하자.

 

 

예외 전환 

낮은 계층(예: JDBC, API)**에서 발생한 예외를
상위 계층(서비스, 도메인) 에 적합한 의미 있는 예외로 바꾸는 것

 

예외 전환 전

public User findById(String id) throws SQLException {
    Connection conn = dataSource.getConnection();
    // ... 생략 ...
    throw new SQLException("No result");  // 그대로 던짐
}

 

예외 전환 후 

public User findById(String id) {
    try {
        // DB 조회
    } catch (SQLException e) {
        throw new UserNotFoundException("사용자를 찾을 수 없습니다", e); // 예외 전환!
    }
}

상위 계층은 이제 UserNotFoundException만 알면 됨.

 

 

Spring은 @Repository를 통해 DAO 계층에서 발생하는 예외를 자동으로 전환시켜준다.

 

Spring은 데이터 접근 계층의 예외를 DataAccessException 계열로 통일시킵니다.

DBC, JPA, MyBatis 등 내부 구현에서 발생한 SQLException 또는 PersistenceException 등을 DataAccessException으로 감싸줍니다.

이를 통해 상위계층(서비스 Layer)은 DB기술에 종속되지 않고 예외를 처리할 수 있습니다.