Error Handling
에러가 런타임에서 성공적으로 확인된 경우,
- 현재 스택에서 함수 실행을 중단하고
- 프로세스 노드에서 프로세스를 종료하고
- 스택을 추적해 콘솔에서 사용자에게 에러에 대한 설명을 제공한다.
- 단순히 에러를 확인만 하지 말고, Handling 하자! - console.log를 사용하면 에러 로그와 헷갈리기 쉽기 때문에 자제하고,
- try - catch문으로 감쌌다면 에러를 예상한 것이므로, 해당 에러에 대한 해결 방안을 마련해 놓아야 한다.
 - 👇 - console.error또는- console.exception활용하기- 1 
 2
 3
 4- console.debug('디버그 메세지'); 
 console.info('정보 메세지');
 console.warn('경고 메세지');
 console.error('에러 입니다.');
- 유저에게 error를 알리기 
- 서비스 자체에 error를 기록하기 
 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22- // bad 
 try {
 functionThatMightThrow();
 } catch (error) {
 // just logging out
 console.log(error);
 }
 // good
 // error "handling"
 try {
 functionThatMightThrow();
 } catch (error) {
 // 1. console.error
 // === console.exception
 console.error(error);
 // 2. 유저에게 알리기
 notifyUserOfError(error);
 // 3. 서비스 자체에 에러 기록하기
 reportErrorToService(error);
 // ... etc
 }
- Promise가 반환한- rejected를 넘기지 말고, Handling 하자!- Handling 방법은 위와 동일하게, 각 에러에 맞게 정의한다. - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24- // bad 
 getdata()
 .then(data => {
 functionThatMightThrow(data);
 })
 .catch(error => {
 // just logging out...
 console.log(error);
 });
 // good
 getdata()
 .then(data => {
 functionThatMightThrow(data);
 })
 .catch(error => {
 // 1.
 console.error(error);
 // 2.
 notifyUserOfError(error);
 // 3.
 reportErrorToService(error);
 // ...etc
 });
기본적인 Handling 방법
JAVA 기준
- 오류 코드보다 - 예외를 사용할 것- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15- public void sendShutDown() { 
 try {
 tryToShutDown();
 } catch (DeviceShutDownError e) {
 logger.log(e);
 }
 }
 private void tryToShutDown() throws DeviceShutDownError {
 DeviceHandle handle = getHandle(DEV1);
 DeviceRecord record = retrieveDeviceRecord(handle);
 pauseDevice(handle);
 clearDeviceWorkQueue(handle);
 closeDevice(handle);
 }
- try-catch-finally부터 작성할 것- try문은 transaction처럼 동작하는 실행코드로,- catch문은 try문에 관계없이 프로그램을 일관적인 상태로 유지하도록 한다.
 
- 예외에 의미를 제공할 것 - 예외를 던질 때는 전후 상황을 충분히 덧붙인다.
- 실패한 연산 이름과 실패 유형도 언급한다.
 
- 호출자를 고려해 예외 클래스를 정의할 것 - 써드파티 라이브러리를 사용하는 경우 그것들을 wrapping함으로써 라이브러리 교체 등의 변경이 있는 경우 대응하기 쉬워진다.
- Wrapper 클래스를 이용하여 호출하는 라이브러리 API를 감싸면서 예외 유형 하나를 반환하므로 의존성이 크게 감소한다.
 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24- try { 
 port.open();
 } catch (PortDeviceFailure e) {
 reportError(e);
 logger.log(e.getMessage(), e);
 } finally {
 ...
 }
 public class LocalPort {
 ...
 
 public void open() {
 try {
 innerPort.open();
 } catch (DeviceResponseException e) {
 throw new PortDeviceFailure(e);
 } catch (ATM1212UnlockedException e) {
 throw new PortDeviceFailure(e);
 } catch (GMXError e) {
 throw new PortDeviceFailure(e);
 }
 }
 }
- 에러 시 - null을 반환하거나 전달하지 말 것
Ref
https://ibrahimovic.tistory.com/39
https://nesoy.github.io/articles/2018-02/CleanCode-ErrorHandle