Java 예외 계층 - 활용
예외를 잡아서 처리할 때 예외 계층을 활용할 수 있다.
만약, NetworkClient 수 많은 예외가 발생한다면?
이런 경우 모든 예외를 하나하나 잡아서 처리하는 것은 시간이 매우 오래 걸릴 것이다.
이전에 예외 계층에서 try ~ catch ~ catch... 이어서 출력한 것을 떠올려 보자.
try {
client.connect();
client.send(data);
} catch (ConnectException e) {
System.out.println("[Error] Connect Failed address: " + e.getAddress() + ", message: " + e.getMessage());
} catch (SendException e) {
System.out.println("[Error] Send Failed message: " + e.getSendData() + ", message: " + e.getMessage());
} finally {
client.disconnect();
}
catch문으로 계속 이어서 예외를 잡으면 불필요한 표시로 가독성이 떨어진다.
그렇다면 새롭게 예외 처리하도록 개선 시도해보자.
예외 처리에 중요, 보통, 낮음으로 나누어주자
- Network에서 연결 오류는 중요한 편이다.
- ConnectException 예외 발생 시 명확한 메시지가 필요하다.
- [Connect Error] Address: ...
- 나머지 에러에 대한 메시지는 단순하게 출력한다.
- [Network Error] Message: ...
- 그 외의 문구는 다음과 같이 출력한다.
- [Unknown Error] Message: ...
- ConnectException 예외 발생 시 명확한 메시지가 필요하다.
NetworkService.class
try {
client.connect();
client.send(data);
} catch (ConnectException e) {
System.out.println("[Connect Error] Connect Failed. address: " + e.getAddress() + ", message: " + e.getMessage());
} catch (NetworkClientException e) {
System.out.println("[Network Error] Send Failed. message: " + e.getMessage());
} catch (Exception e) {
System.out.println("[Unknown Error] Failed. message: " + e.getMessage());
} finally {
client.disconnect();
}
Send Message data: error1
[Connect Error] Connect Failed. address: http://kiioio.com is Connect Open Failed, message: http://kiioio.com
http://kiioio.com Connect Closed Success
Send Message data: error2
http://kiioio.com Connect Open Success
[Network Error] Send Failed. message: http://kiioio.comSend Failederror2
http://kiioio.com Connect Closed Success
Send Message data: ap
http://kiioio.com Connect Open Success
http://kiioio.com Send Message data: ap
http://kiioio.com Connect Closed Success
코드를 살펴보면 알겠지만 catch 건너뛸 때마다 예외 계층 구조로 만든 것이 자기의 부모 예외로 이동한다. 왜냐면 부모는 자식을 모두 담고 있기 때문에 포괄적으로 예외를 잡아준다.
- catch 문은 처음 마주치는 것부터 동작한다.
- catch 문으로 예외를 넘어갈수록 부모 예외 객체로 잡아주어야 한다.
- 반대로 한 경우 컴파일 오류 발생함.
catch 문 예외 계층 둘 중 하나 잡기
catch 에는 예외 계층 하나가 아닌 아니라 여러 개 예외 객체를 넣을 수 있다.
try {
client.connect();
client.send(data);
} catch (ConnectException | SendException e) {
System.out.println("[Connect Error or Network Error] Failed. message: " + e.getMessage());
} finally {
client.disconnect();
}
- 공통 예외를 한번에 잡아준다. 이 경우 ConnectException, SendException 각자의 멤버필드를 사용할 수 없다.
- 멤버 필드를 사용 해야한다면 둘의 부모인 NetworkClientException 멤버필드를 사용해주어야 한다.
예외 활용 정리
- 예외 계층화로 다양하게 만들 수 있고 세밀한 동작을 깔끔하게 처리할 수 있다.
- 또는 공통 예외로 여러 예외를 넣어서 catch 키워드 하나로 잡을 수 있다.