자바 예외 이해

개발하는 도비·2023년 10월 5일

spring-db

목록 보기
5/7
post-thumbnail

1. 예외 계층

  • 구조
  • 주요 클래스
    • Throwable : 최상위 예외. 하위에 ExceptionError 가 있음.
    • Error : 메모리 부족이나 심각한 시스템 오류와 같이 애플리케이션에서 복구 불가능한 시스템 예외. 애플리케이션 개발자는 이 예외를 잡으려고 해서는 안된다.
      • 상위 예외를 catch 로 잡으면 그 하위 예외까지 함께 잡는다. 따라서 애플리케이션 로직에서는 Throwable 예외도 잡으면 안되는데, 앞서 이야기한 Error 예외도 함께 잡을 수 있기 때문. 애플리케이션 로직은 이런 이유로 Exception 부터 필요한 예외로 생각하고 잡으면 된다.
      • 언체크 예외
    • Exception : 체크 예외
      • 애플리케이션 로직에서 사용할 수 있는 실질적인 최상위 예외이다.
      • Exception과 그 하위 예외는 모두 컴파일러가 체크하는 체크 예외. RuntimeException 은 예외로 한다.
    • RuntimeException : 언체크 예외, 런타임 예외
      • 컴파일러가 체크 하지 않는 언체크 예외이다.
      • RuntimeException 과 그 자식 예외는 모두 언체크 예외이다.

2. 예외 기본 규칙

  • 예외 처리

  • 예외 던짐

  • 예외 2가지 기본 규칙

    • 예외는 잡아서 처리하거나 던져야 함.
    • 예외를 잡거나 던질 때 지정한 예외뿐만 아니라 그 예외의 자식들도 함께 처리됨

3. 체크 예외 기본 이해

  • Exception, RuntimeException 상속 받아 예외를 만들 수 있음.
  • 장점
    • 개발자가 실수로 예외를 누락하지 않도록 컴파일러를 통해 문제를 잡아주는 안전 장치
  • 단점
    • 하지만 실제로는 개발자가 모든 체크 예외를 반드시 잡거나 던지도록 처리해야 하기 때문에 번거로움.
  • 장단점 모두 존재
    • 체크 예외는 예외를 잡아서 처리할 수 없을때, 예외를 밖으로 던지는 throws예외를 필수로선언해야 함.

4. 언체크 예외 기본 이해

  • RuntimeException과 그 하위 예외는 언체크 예외로 분류.
  • 언체크 예외는 컴파일러가 예외를 체크하지 않는다는 뜻.
  • 예외를 던지는 throws 를 선언하지 않고, 생략할 수 있다. 이 경우 자동으로 예외를 던짐.
  • 장점
    • 신경쓰고 싶지 않은 언체크 예외를 무시할 수 있다. -> throws를 생략 가능.
  • 단점
    • 개발자가 실수로 예외를 누락할 수 있음.

5. 체크 예외 활용

  • 기본적으로 언체크(런타임) 예외를 사용
  • 체크 예외는 비즈니스 로직상 의도적으로 던지는 예외에만 사용
    • 반드시 처리해야 하는 문제일 때만 체크 예외를 사용
    • ex) 로그인 ID, PW 불일치 예외

5-1. 체크 예외의 문제점

  • 리포지토리는 DB에 접근해서 데이터를 저장하고 관리한다. 여기서는 SQLException 체크 예외를 던짐.

  • NetworkClient 는 외부 네트워크에 접속해서 어떤 기능을 처리하는 객체. ConnectException 체크 예외 던짐

  • 서비스는 리포지토리와 NetworkClient를 둘다 호출

    • SQLExceptionConnectException를 모두 처리해야함.
  • 서비스는 SQLExceptionConnectException를 처리할 수 없으므로 둘다 밖으로 던짐.

    • method() throws SQLException, ConnectException와 같이 선언 해야함.
  • 컨트롤러도 두 예외를 처리할 방법이 없음.

    • method() throws SQLException, ConnectException와 같이 선언 해야함.
  • 웹 애플리케이션이라면 서블릿의 오류 페이지나, 또는 스프링 MVC가 제공하는 ControllerAdvice에서 이런 예외를 공통으로 처리.

  • 정리

    • 복구 불가능한 예외
      • 대부분의 경우
      • SQLException의 경우 SQL 문법, 데이터베이스 자체, 서버가 중간에 다운등의 문제가 있을 수 있음. 이런 문제는 서비스나 컨트롤러가 해결할 수가 없음. 서블릿 필터, 스프링 인터셉터, 스프링의 ControllerAdvice를 사용해 공통으로 해결
    • 의존 관계에 대한 문제
      • JDBC -> JPA로 기술이 바뀔 경우 문제가 생김.
      • SQLExceptionjava.sql.SQLException에 의존함.

6. 언체크 예외 활용

  • 예외 전환 (강의 자료 코드 기준으로 설명 작성)
    • SQLException -> RuntimeSQLException으로 전환해서 예외를 던짐
    • 다른 체크예외도 마찬가지로 변경
  • 정리
    • 런타임 예외 - 대부분 복구 불가능한 예외
      • 런타임 예외를 사용하면 서비스나 컨트롤러가 이런 복구 불가능한 예외를 신경쓰지 않아도 됨
    • 런타임 예외 - 의존 관계에 대한 문제
      • 런타임 예외는 해당 객체가 처리할 수 없는 예외는 무시하면 됨.

6-1. 런타임 예외 구현 기술 변경시 파급 효과

  • 런타임 예외를 사용하면 중간에 기술이 변경되어도 해당 예외를 사용하지 않는 컨트롤러, 서비스에서는 코드를 변경하지 않아도 됨.
  • 구현 기술이 변경되는 경우, 예외를 공통으로 처리하는 곳에서는 예외에 따른 다른 처리가 필요할 수 있다. 하지만 공통 처리하는 한곳만 변경하면 되기에 영향 범위를 최소화할 수 있다.

7. 예외 포함과 스택 트레이스

  • 예외를 전한활 때는 기존 예외를 포함할 것.
//기존 예외 포함
public void call() {
	try {
		runSQL();
	} catch (SQLException e) {
		throw new RuntimeSQLException(e); //기존 예외(e) 포함 
    }
}
//기존 예외 미포함
public void call() {
	try {
		runSQL();
	} catch (SQLException e) {
		throw new RuntimeSQLException();  
    }
}

8. 참조

  • 스프링 DB 1편 - 데이터 접근 핵심 원리
  • 링크
profile
도비의 양말을 찾아서

0개의 댓글