사다리 게임 미션 진행 중 입력에 대한 예외처리를 해주기 위해 다음과 같이 코드를 작성했다.
private People inputPeople() {
try {
return ladderService.people(InputView.personNameInput());
} catch (Exception e) {
e.printStackTrace();
OutputView.inputPeopleException();
}
return inputPeople();
}
리뷰어님께서 "printStackTrace()
는 사용하지 않는 것이 권장됩니다. 왜 그럴까요?" 리뷰를 남겨주셔서 이유를 찾아보았다.
우선 Throwable.printStackTrace()
의 내부 구현을 살펴보자
System.err
를 PrintStream
으로 사용하고 있다.
실제 출력 부분의 코드에서는 System.err
의 출력 스트림에 Throwable
과 StackTraceElement
를 가져와 출력하는 것을 볼 수 있다.
getOurStackTrace()
의 경우 StackTraceElement.of
를 통해 StackElement를 가져오는데
of
메서드 내부에서 computeFormat()
를 호출하는데 이 코드 내부를 보면
Reflection을 사용하는 것을 볼 수있다.
내부 동작을 살펴봤으니 본격적으로 Throwable.printStackTrace()
를 사용하면 안되는 이유를 알아보자
1. 오류 출력이 실제로 어디로 가는지 알 수 없다.
System.err
는 System.setErr()
를 통해 변경될 수 있으므로 이 오류가 어디에 출력되는 것인지 알 수 없다.
2. 많은 오버헤드가 발생한다.
내부에서 동기화를 위한 synchronized, Reflection 호출 등 많은 오버헤드가 발생한다.
3. 보존 정책을 설정할 수 없다.
보존 정책을 설정할 수 없으므로 기본적으로 Log가 Application 생명주기와 함께한다.
4. 보안성이 떨어진다
StackTrace를 통해 메서드 내부 동작 구조가 노출되기 때문에 보안성이 떨어지므로 외부에 노출해선 안된다.
logback, slf4j, java.util.logging, log4j 등 로그가 기록되는 위치와 보존 정책을 설정할 수 있으므로 로깅 프레임워크를 사용하자
https://stackoverflow.com/questions/7469316/why-is-exception-printstacktrace-considered-bad-practice