Java 예외 계층
이전 작성글 "Java 예외 처리 - 네트워크 예제 리팩토링 1" Network 코드에 대한 설명을 진행하였다. 이 코드가 어떤 것이었는지 떠올리며 예외 구조를 계층적으로 진행해보자.
체크 예외
+-----------+
| Exception |
+-----+-----+
|
+-----------+------------+
| NetworkClientException |
+-----------+------------+
|
+-----------------------+ | +------------------------+
| ConnectException +---+---+ SendException |
| field::String address | | field::String sendData |
+-----------------------+ +------------------------+
- NetworkClientException
- NetworkClient 발생한 예외는 이 예외의 자식으로 이어져 있다.
- ConnectException
- 연결 실패 시 발생하는 예외. 내부에 연결 시도한 address 메시지를 보관
- SendException
- 전송 실패시 발생하는 예외. 내부에 전송 시도한 데이터 sendData 를 보관
예외는 오류 코드 분류가 아닌 예외를 계층적으로 다양하게 만들어 세밀하게 처리할 수 있다.
다음 이렇게 예외를 계층화 하면 장점이 무엇인가
- 자바에서 다루는 예외는 객체로 부모 예외를 잡거나 던질 경우 자식 예외도 함께 처리할 수 있다.
- NetworkClientException 예외를 잡아 ConnectException, SendException 예외를 함께 잡는다.
- NetworkClientException 이 아닌 특정 예외로 ConnectException, SendException 선택해 예외를 처리할 수 있다.
예외 계층 구조 작성하기
NetworkClientException.class
public class NetworkClientException extends Exception {
private String errorCode;
public NetworkClientException(String message) {
super(message);
}
}
ConnectException.class
public class ConnectException extends NetworkClientException {
private final String address;
public ConnectException(String errorCode, String message, String address) {
super(message);
this.address = address;
}
public String getAddress() {
return address;
}
}
- 연결 실패 시 발생되는 예외.
- 필드는 address 주소를 갖고 있다.
- NetworkClientException 상속 받는다.
SendException.class
public class SendException extends NetworkClientException {
private final String sendData;
public SendException(String sendData, String message) {
super(message);
this.sendData = sendData;
}
public String getSendData() {
return sendData;
}
}
- 전송 실패 시 발생되는 예외
- 필드는 sendData 를 갖고 있다.
- NetworkClientException 상속 받는다.
NetworkClient.class
public class NetworkClient {
private final String address;
public boolean connectError;
public boolean sendError;
public NetworkClient(String address) {
this.address = address;
}
public void connect() throws ConnectException {
// exception error
if (connectError) {
throw new ConnectException(address, address + " is Connect Open Failed");
}
// Connect Success
System.out.println(address + " Connect Open Success");
}
public void send(String data) throws SendException {
if (sendError) {
throw new SendException(data, address + " Send Failed data: " + data);
}
// 전송 성공
System.out.println(address + " Send Message data: " + data);
}
public void disconnect() {
System.out.println(address + " Connect Closed Success");
}
public void initError(String data) {
if (data.contains("error1")) {
connectError = true;
}
if (data.contains("error2")) {
sendError = true;
}
}
}
- 이전 작성 글의 NetworkClient 코드를 가져와 수정한 것이다.
- connect(), send() 부모를 바꾸고 예외 생성 코드를 바꾸고 나머지는 동일하다.
예외가 터진 경우 이전에는 NetworkClientException 사용하였을 때는 어떻게 오류가 터졌는지 연결인지 연결 해제인지 전송 문제인지 모른다.
그러나 예외를 계층을 나누어 표현하면 연결, 연결해제, 전송 문제인지 한번에 인지할 수 있다.
NetworkService.class
public class NetworkService {
public void sendMessage(String data) {
String address = "http://kiioio.com";
NetworkClient client = new NetworkClient(address);
client.initError(data); // 오류 코드로 반환.
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();
}
}
}
- 예외 클래스는 상황에 맞게 코드를 작성한다.
- 예외 클래스의 고유한 기능 e.getAddress(), e.getSendData() 기능으로 정보를 출력한다.
Main.class
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
NetworkService networkService = new NetworkService();
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print("Send Message data: ");
String input = scanner.nextLine();
if (input.equals("exit")) {
break;
}
networkService.sendMessage(input);
System.out.println();
}
System.out.println("네트워크 프로그램 종료");
}
}
Send Message data: hello
http://kiioio.com Connect Open Success
http://kiioio.com Send Message data: hello
http://kiioio.com Connect Closed Success
Send Message data: error1
[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
[Error] Send Failed message: error2, message: http://kiioio.com Send Failed data: error2
http://kiioio.com Connect Closed Success
Send Message data: exit
네트워크 프로그램 종료
코드로 확인하니 예외 코드가 명확하고 간결하다.