# 예외는 무엇이고, 예외처리는 어떻게 하는가
이 글은 자바에 한정해서 예외를 설명합니다.
# 예외란 무엇인가
- 오라클 문서에 따르면, 예외는 프로그램 실행중에 정상적인 흐름을 방해(disrupt) 시키는 이벤트이다.
# 예외가 어떻게 발생되고 어떻게 처리되는가
- 메서드 안에서 에러가 발생하면, 메서드는 예외 개체(Exception Object)를 런타임 시스템에 건네준다.
- 예외 개체 : 에러에 대한 정보를 저장
- 예외 타입
- 상태
- 예외 개체를 런타임 시스템에 건네주는것을 예외를 던진다(throwing an exception)라고 말한다.
- 예외 개체 : 에러에 대한 정보를 저장
- 런타임 시스템은 예외를 처리할수 있는 대상을 찾으려고 할것이다. 메서드 콜스택을 탐색하면서 해당 메서드가 예외를 처리할수있는 코드 블록을 갖고있는지 보는 것이다.
- 적절한 exception handler 를 찾으면 런타임 시스템은 핸들러에게 예외를 전달해준다.
- 핸들러가 처리할수있는 예외 유형과 던져진 예외 유형이 일치한다면 적절하다고 간주한다.
- 이때 예외를 catch 했다고 말한다.
# 예외 종류
- Error
- Exception
- checked exception : RuntimeException 을 상속하지않은 클래스
- uncheked exception : RuntimeException 을 상속한 클래스
checked exception 의 경우에는 예외를 처리하는 코드를 작성하거나 catch 문으로 잡거나 메서드 선언부에 throws를 선언해서 메서드 밖으로 던져야한다. 그러지않을경우 컴파일 에러가 발생한다. 주로 일반적인 종류의 예외 상황이나 복구할 가능성이 있는 예외 상황을 다룬다. 하지만, 최근에는 항상 복구할수있는 상황이 아니라면 언체크 예외로 만드는 경향이 있다고 한다.
ex) SQLException, IOException, ..
unchecked exception 의 경우에는 명시적인 예외 처리를 강제하지 않기때문에 언체크 예외라고 불리는 것이다.
즉 메서드 선언부에 throws 를 넣지않아도 무방하다.
ex) NullPointerException, IllegalArgumentException, ..
# 예외 처리 방법
# 예외 복구
예외가 발생하면 적절한 처리를 해서 문제를 해결한다.
예를들어 네트워크 상태가 안좋아서 db 접근시 SqlException 이 발생한다면, 여러번 db 접근 시도를 한다던지 방법으로 해결할수있다.
# 예외처리 회피(throws)
예외처리를 자신이 담당하지않고 자신을 호출한쪽으로 던져버리는것이다. 메서드에 throws 문으로 선언해서 예외가 알아서 던져지게 하거나, catch 문으로 예외를 잡은후에 로그를 남기고 다시 예외를 던져버리는것이다.
물론 이는 의도가 분명해야한다. 자신을 호출 하는 쪽에서 예외를 처리하는게 최선이라는 확신이 있어야한다. 예를들어 DAO 에서 SqlException 을 생각없이 던져버린다면, dao 를 호출한 서비스 계층은 이를 처리하지도 못하고, 처리할 책임도 없다. 무책임하게 예외를 던져버리는 방식은 지양해야한다.
# 예외 전환(Exception Translation)
예외가 발생하면 예외를 적절한 예외로 전환하여 메소드 밖으로 던진다.
목적
예외 상황에 대한 적절한 의미로 바꿔주기 위해서, 적합한 의미를 가진 예외로 바꿔주는 것이다.
예를 들어, 회원 가입시에 아이디가 중복인 유저가 있어서 DB 에러가 발생하면 JDBC API 는 SQLException 을 던지는데, 이 예외를 전달 받게되는 서비스 계층에서는 왜 SQLException 이 발생한 것인지 알수가 없다.
이런 경우에 DuplicateUserIdException 이라는 예외로 전환해서 throw 할수있는것이다.
어차피 대응이 불가능한 체크예외라면, 런타임 예외로 포장해서 던져버리고 로그를 상세히 남기거나 관리자에게 메일로 통보한다거나 사용자에게 안내 메시지를 보낸다는 식의 처리를 할수도 있다.
# Refrence
- https://docs.oracle.com/javase/tutorial/essential/exceptions/definition.html