예외 (Exception)는 개발자가 구현한 로직에서 발생합니다.
그렇기 때문에 에러 (Error) 와 달리 상황을 미리 예측하여 처리할 수 있습니다.
따라서 이러한 예외를 구분하고 그에 따라 명확하게 처리 하는것 이 중요합니다.
1. 예외 클래스
위 [그림1]은 예외클래스의 구조입니다.
Exception 과 Error 클래스가 Throwable 클래스를 상속받고 있습니다.
Error 는 시스템 레벨에서 비정상적인 상황이 생겼을때 발생하기 때문에 개발자가 미리 예측할 수 도 없고 처리할수도 없습니다. 따라서 애플리케이션에서 개발자가 Error 에 대한 처리를 신경 쓰지 않아도 됩니다.
반면, Exception 은 개발자가 직접 처리를 할 수 있습니다.
2. Checked Exception 과 Unchecked Exception
Checked Exception | Unchecked Exception | |
처리 여부 | 반드시 예외 처리 해야함 | 명시적인 예외 처리 하지 않아도 됨 |
확인시점 | 컴파일 단계 | 실행단계 |
예외발생시 트랜잭션 처리 | roll-back 하지 않음 | roll-back 함 |
대표 Exception |
Exception 의 상속받는 하위 클래스 중 Runtime Exception 을 제외한 모든 예외 IOException SQLException ClassNotFoundException ... |
Runtime Exception 하위 예외 NullPointerException SystemException ... |
예외처리 여부
Checked Exception 과 Unchecked Exception 의 가장 구분점은 예외 발생상황에서 처리유무 입니다.
Checked Exception 은 컴파일 단계에서 명확하게 Exception 체크가 가능하여 try/catch 로 감싸거나 throws 로 던지지 않으면 컴파일 에러가 발생 합니다.
반대로 Unchecked Exception 은 실행과정 중 발생되는 예외로 컴파일 단계에서 확인 할 수 없고, 실행과정중에 발생 된다 하여 Runtime Exception 이라 합니다.
Rollback 여부
기본적으로 Checked Exception 은 예외가 발생하면 트랜잭션을 rollback 하지 않고, Unchecked Exception 은 예외 발생 시 rollback 처리 합니다.
따라서 개발자가 이를 인지하지 못하고 Checked Exception 상황에서 무분별한 throws 및 적절하지 못한 예외 처리를 한다면, 심각한 시스템 결함을 초래 할 수 있습니다.
3. Chedked Exception 예외 처리 전략
3-1. 예외 복구
예외를 try/catch 로 잡아서 적절한 처리를 하여 다른 작업흐름으로 유도 합니다.
예외복구는 예외가 발생하여도 애플리케이션은 정상적인 흐름으로 진행되어야 할때 사용하는 전략 입니다.
try {
process();
} catch (IOException e) { // Better Code
log.error("Service Layer IOException {}", e.getMessage(), e);
throw e
}
3-2. 예외처리 회피
예외가 발생하면 throws 를 통해 호출한쪽으로 예외를 던지고 처리를 회피합니다.
이 전략은 명확하게 호출한 곳에서 처리하는 것이 최선이라는 확신이 있을때만 사용해야 합니다.
public void updateUser throws NullPointerException {
....
}
3-3. 예외 전환
try/catch 문에서 예외를 잡아서 다른 예외를 던지는 방법입니다.
Checked Exception 중 복구가 불가능한 예외가 잡혔다면 이를 Unchecked Exception 으로 전환하여 다른 계층에서 일일이 예외를 선언할 필요가 없도록 하기 위함입니다.
private void registStartAuctionJob(String rfxId, Date rfxStartDt, Object[] args) {
try {
scheduleService.registSchedule(
Class.forName(AuctionJobConst.AUCTION_SERVICE_CLASS_NAME),
AuctionJobConst.AUCTION_START_METHOD_NAME,
args,
rfxStartDt,
AuctionJobConst.AUCTION_JOB_GROUP,
rfxId,
AuctionJobConst.AUCTION_START_JOB_NAME,
null);
} catch (ClassNotFoundException e) {
throw new CommonException(ErrorCode.FAIL, e);
}
}
일반적인 웹 애플리케이션이라면..
웹 애플리케이션 특성상 Checked Exception 일 경우라도 복구 할 수 없고, 원복해야하는 프로세스가 대부분 입니다. 또한 throws 하더라도 호출하는 쪽에서 별도로 처리 할 수 있는게 없기 때문에
예외 복구 나 예외 처리 회피가 무의미해지는 경우가 많습니다.
가능한 빨리 이를 RuntimeException 으로 포장하여, 무차별 throws 를 선언하지 않도록 해주는 것이 좋습니다.
'개발노트 > SPRING' 카테고리의 다른 글
Gson 직렬화 시 Null object field 처리 (0) | 2020.03.25 |
---|