예외처리에 대한 생각
프로그램에서 예외는 발생할 수 밖에 없고, 특히 예외로 인해 서버 프로그램이 작동을 멈춘다면 문제가 발생할 요소가 있다. 적어도 발생한 예외가 어떤 예외이며, 이것이 무시해도 될 수준인지 아니면 반드시 처리를 해야하는 것인지 그것도 아니라면 시스템 자체를 종료시켜야하는지에 대해 생각해봐야한다.
시스템에서 훌륭한 기능보다 중요한 것이 손쉬운 보완이라고 생각한다. 예외는 프로그램의 보완에 있어 첫걸음이 될 것이다.
첫 단추를 잘 꿰 메야 한다는 말이 있듯이, 프로그램을 설계하고 구축하는 첫 단계에서 수많은 예외상황에 생각하고자 스스로 노력하자.
1. 에러와 예외는 어떻게 다른가?
error : 시스템 단계에서 발생. 시스템의 비정상적인 상황이므로 예외처리가 아닌 시스템 환경을 개선해야 한다.
Exception : 프로그램 로직에서 발생. 프로그래머가 작성한 로직에서 예외를 예상하여 구분하고 처리해야 한다.
2. 예외의 구분
예측가능한 예외 vs 예측 불가능한 예외
* 예측 가능한 예외
- 프로그램에서 당연히 발생 할 수 밖에 없는 상황. ex) 로그인 실패, 데이터 조회 실패 .. 등
* 예측 불가능한 예외
- 에러와 같은 수준의 레벨. ex) 버그, 시스템의 메모리 문제 .. 등
- 시스템 환경에서 개선해야 한다.
Runtime Exception vs 그 밖의 예외
* Runtime Exception (unchecked Exception)
- 실행 단계에서 확인합니다.
- 그렇기 때문에 처리를 강제하지 않습니다.
- ex) nullpointerException , IndexOutOfBoundsException, .. 등
- 하지만 이 또한 버그이기 때문에 반드시 인지하고 처리해야 할 의무가 있습니다.
* 그 밖의 예외 (checked Exception)
- 컴파일 단계에서 확인합니다.
- 예외에 대한 처리를 강제합니다.
- ex) IOException ..
3. 예외를 잡은 이 후의 행동
(1) 예외를 잡았다면 반드시 처리해야 한다.
- 하지만 그 예외가 에러라면? 저라면 시스템 환경을 개선하고 처리하지 않겠습니다.
- 시스템을 종료하거나 혹은 예외에 대한 상황을 처리 할 수 있다.
(2) 로그를 반드시 남겨야 한다.
- 예외가 어떤 예외인지 구체적으로 명료하게 로그로 남겨야 한다.
- 예외가 발생한 원인, 시스템의 정보, 이외 반드시 판단 가능한 메세지.
- 로그는 프로그래머가 처리 상황을 판단 할 수 있는 구체적인 증거입니다. 특히 서버 개발자에겐..
(3) 새로운 예외를 던질 수 있다.
- 세세한 예외를 더 추상화하여 던진 경우이다.
- 예외 원인에 대한 정보가 부족할 경우 새로운 예외를 던짐으로써, 구체적인 정보를 얻을 수 있다.
(4) 예외 무시
- 큰 이상이 없다고 판단되면 예외를 무시할 수 있다.
- 좋은 방법은 아니다.
4. 예외처리 패턴
(1) 예외복구
try{
....
}
catch(SQLException e) {
logger.error("Insert Query Failed . Method Name '' , User id is blar...");
e.printstackTrace();
}finnally{
..
예외에 대한 처리작업을 수행해야 할 것이다.
doAnything();
}
=> 예외복구에 대해 반드시 인지해야 되는 점은 프로그램이 정상적으로 작동하게끔 수행해야 한다는 것이다. 비록 예외가 발생되었어도 프로그램 로직에 의해 시스템이 종료 혹은 계속해서 수행할 수 있어야 할 것이다.
(2) 예외회피
public void process() throws Exception {
......
}
=> 예외를 메소드에 정의함으로써, 예외에 대한 처리를 수행하지 않고 있다. 또한 추상클래스인 Exception을 예외로 던졌기 때문에, 구체적인 예외에 대한 처리가 부족하다. 즉, 좀 더 세부적인 예외를 잡아먹고 있다. 예외회피를 불가피하게 해야할 경우를 제외한다면, 신중하게 선택해야 할 것이다.
(3) 예외전환
try{
....
}
catch(Exception e) {
... 추상 Exception에 대한 정보 또한 로그로 남기면 좋을 것이다..
throws New SQLException("Exception is SQLException. Insert Query Failed . Method Name '' , User id is blar...");
}
=> 예외를 중첩하여 사용하여 어떤 예외에 대한 처리인지 분명하게 처리하였다. 만일 복구가 불가능 한 예외에 대한 처리라면 RuntimeException으로 전환하여 다른 예외에 대해 일일히 처리하지 않게끔 할 수 있다.
예외에 대해 정리하면서 느낀 생각은, 개발자라면 항상 예외에 대해 염두하고 있어야 한다는 점입니다. (특히 나같은 초급개발자라면..)
예외를 잡았다면 반드시 처리해야 할 것이며, 예외 상황에 대한 충분한 로그를 남겨야 할 것입니다. 충분히 예외상황에 대해 인지하고 처리를 했다면 유지보수 측면에서 혹은 협업단계에서 효율적으로 시스템을 개선할 수 있을 것입니다.
=> 예외의 목적은 시스템 개선이다!!
참고사이트 : https://www.slideshare.net/dhrim/ss-2804901