본문 바로가기
Development/Spring

빠르게 실패 vs 안전하게 실패

by 메정 2021. 9. 23.

예외의 종류와 처리 방법

예외(Exception)

java.lang.Exception 클래스의 서브 클래스들은 Error와 달리 애플리케이션 코드에서 예외가 발생하였을 경우에 사용

체크예외와 언체크예외로 구분

gd3

  1. 체크 예외(Check Exception)
    • RuntimeException 클래스를 상속하지 않은 Exception 클래스들
    • 체크 예외는 예외가 발생할 수 있는 메소드를 사용할 경우 반드시 예외를 처리하는 코드를 함께 작성해야 함.
    • try-catch 문으로 잡거나 throws를 통해 예외를 던져야 함.
    • 만약 예외를 처리하지 않으면 컴파일 에러가 발생
  2. 언체크 예외(Uncheck Exception)
    • RuntimeException 클래스를 상속한 Exception 클래스들은 예외처리를 강제하지 않기 때문에 언체크 예외라고 불림.
    • 에러를 처리하지 않아도 컴파일 에러가 발생하지 않음
    • 프로그램에 문제가 있을 때 오류가 발생하도록 의도된 예외가 RuntimeException.
      • NullPointerException or IllegalArgumentException 등이 대표적
      • 개발자 부주의로 발생하는 경우 문제를 유발하도록 만들어짐

올바른 예외처리 방법

1. 상황에 맞는 try-catch로 조치 진행

try-catch로 예외를 잡았지만, 던지지 않는 등 조치를 취하지 않는 것은 안됨!

예외가 발생했지만, 이를 무시하는 꼴

어떤 기능이 비정상적으로 동작하거나 메모리, 리소스 고갈 등의 문제가 야기될 수 있음

예외처리 시 적절한 조치를 통해 상황을 복구하거나 작업을 중단시키고, log를 남겨야 함

2. 무분별한 throws Exception을 언체크 예외로 전환

public void method1() throws Exception {
        method2(); 
} 

public void method2() throws Exception {
        method3(); 
} 

public void method3() throws Exception { }

어디서, 어떤 문제로 예외가 발생했는지에 대한 유의미한 정보를 얻을 수 없음

SQLExcception과 같이 복구가 불가능한 예외의 경우 throws를 던지지 않고, 언체크(런타임) 예외로 전환해주는 것이 좋음

안전하게 실패하기

버그, 입출력 문제, 메모리 오버플로우 등이 발생한 상황에서도 소프트웨어가 계속 실행될 수 있도록 소프트웨어는 생존하기 위해 노력함

NULl을 반환하는 방법도 일종의 생존 기법.

만약, 디렉토리에 포함된 모든 파일을 나열하는 요청에서 비어있다면 이작업은 처리하기 불가능함.

이것은 전적으로 요청자의 잘못이지만, 안전하기 실패하기에서는 이 상황을 구조하기 위해 노력합니다. 아무도 반환한 배열을 사용하지 않아서 NullPointerException이 발생하지 않을 것이라는 희망을 품음

빠르게 실패하기

일단 문제가 발생하면 곧바로 실행을 중단하고 최대한 빨리 예외를 던짐. 실패를 분명하게 만듦

  • 비즈니스 로직에 대한 처리 결과가 null 인경우, null을 절대로 반환하지 말 것
  • 체크 에외를 던지기!
//실패 경우에 대해 exception을 던져 코드를 간결하게
if(!checkEmailDuplicate(user.getEmail()) {
   throw new DuplicatedException("UserService");
}
userRepository.save(user);

참고

댓글