Java 예외 - 실무에서의 처리 공통 예외 처리 구현
네트워크 예제를 가지고 처리가 불가능한 예외를 공통으로 처리하기
언체크 예외
+------------------+
| RuntimeException |
+---------+--------+
|
+-----------+------------+
| NetworkClientException |
+-----------+------------+
|
+-----------------------+ | +------------------------+
| ConnectException +---+---+ SendException |
| field::String address | | field::String sendData |
+-----------------------+ +------------------------+
- 언체크 예외 사용에는 RuntimeException 상속 받아 예외 객체를 생성한다.
- NetworkClientException 생성한 예외 객체과 상속 받은 자식은 모두 언체크 예외가 되었다.
NetworkClientException.class
public class NetworkClientException extends RuntimeException {
public NetworkClientException(String message) {
super(message);
}
}
ConnectException.class
public class ConnectException extends NetworkClientException {
private final String address;
public ConnectException(String message, String address) {
super(message);
this.address = address;
}
public String getAddress() {
return address;
}
}
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;
}
}
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() {
// 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) {
if (sendError) {
throw new SendException(data, address + " Send Failed" + 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;
}
}
}
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);
} finally {
client.disconnect();
}
}
}
- 네트워크, 데이터베이스 예외는 공통 예외 처리로 여기서 진행하지 않는다.
- 연결과 관련된 예외를 없애준다.
- ConnectException, SendException 예외가 발생하여도 해당 오류는 복구가 불가능하다.
- ConnectException, SendException 예외 발생 시 밖으로 던진다.
- 해결 할 수 없는 예외 없어져 본래의 코드에 집중할 수 있어서 가독성이 좋아졌다.
Main.class
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;
}
// 공통 예외 처리
try {
networkService.sendMessage(input);
} catch (Exception e) {
exceptionHandler(e);
}
System.out.println();
}
System.out.println("네트워크 프로그램 종료");
}
// 공통 예외 처리 메소드
private static void exceptionHandler(Exception e) {
// 공통 처리 로직
System.out.println("알 수 없는 문제가 발생하였습니다.");
System.out.println("[DEBUG] ");
e.printStackTrace(System.out);
}
}
Send Message data: error2
http://kiioio.com Connect Open Success
http://kiioio.com Connect Closed Success
알 수 없는 문제가 발생하였습니다.
[DEBUG]
SendException: http://kiioio.com Send Failederror2
at NetworkClient.send(NetworkClient.java:22)
at NetworkService.sendMessage(NetworkService.java:10)
at Main.main(Main.java:18)
Send Message data: error1
http://kiioio.com Connect Closed Success
알 수 없는 문제가 발생하였습니다.
[DEBUG]
ConnectException: http://kiioio.com
at NetworkClient.connect(NetworkClient.java:13)
at NetworkService.sendMessage(NetworkService.java:9)
at Main.main(Main.java:18)
Send Message data: exit
네트워크 프로그램 종료
Main 에서 공통 예외를 처리되어 오류 문구를 사용자에게 표시하고 다른 개발자에게 인지시켜 오류를 처리한다.
- Exception 잡아 해결 못하는 예외는 공통으로 처리가 가능하다.
- 예외는 객체이므로 메소드 인자로 객체를 전달한다.
exceptionHandler() 메소드
- 개발자가 해결할 수 없는 예외 발생 시 사용자에게 알림을 보내도록 처리해야한다.
- 디테일 오류 문구는 보내지 않아도 된다.
- 개발자는 문제를 찾아 디버깅에 용이한 오류 문구를 남겨야 한다.
- 예외는 객체이므로 instanceof 키워드로 객체 타입을 확인하여 다운캐스팅된 자식클래스를 처리할 수 잇다.
printStackTrace() 메소드
- 예외 메시지의 스택 메시지를 출력한다.
- 예외가 발생한 지점을 추적할 수 있다.
- printStackTrace(System.out) 인자로 표준 출력한다.
- printStackTrace(System.err) 인자로 표준 오류로 출력한다.
- IDE 에서는 빨강색이 표시
- 콘솔로만 표시된다.
- 스프링에서 파일 저장되는 SLF4J 또는 Logback 으로 사용해서 활용되지 않음
다운캐스팅으로 예외를 별도 처리하기
만약 특정 예외가 들어온 경우 다운캐스팅하여 멤버필드를 불려와 메시지를 표시할 수 있다.
Main.class
// 공통 예외 처리 메소드
private static void exceptionHandler(Exception e) {
// 공통 처리 로직
System.out.println("알 수 없는 문제가 발생하였습니다.");
System.out.println("[DEBUG] ");
e.printStackTrace(System.out);
if (e instanceof SendException error) {
System.out.println("[Send Error] Send Mesage: " + error.getSendData());
}
}
Send Message data: error2
http://kiioio.com Connect Open Success
http://kiioio.com Connect Closed Success
알 수 없는 문제가 발생하였습니다.
[DEBUG]
SendException: http://kiioio.com Send Failederror2
at NetworkClient.send(NetworkClient.java:22)
at NetworkService.sendMessage(NetworkService.java:10)
at Main.main(Main.java:18)
[Send Error] Send Mesage: error2
다운캐스팅된 SendException 객체를 불려와 멤버필드를 불려와 보냈던 메시지가 무엇인지 출력할 수 있다.