Error Handling

lee jae hwan·2022년 7월 31일

javascript

목록 보기
71/107
try {
  setTimeout(function() {
    noSuchVariable; // 스크립트는 여기서 중단된다.
  }, 1000);
} catch (e) {
  alert( "작동 멈춤" );
}

try..catch는 동기적으로 수행되기때문에 위와같이 비동기함수 내부에서 에러가 던저지면 처리할 수 없다.

이벤트루프 코드블럭과 setTimeout함수 코드블럭은 독립적인 코드블럭이기 때문에 처리할 수 없다.

setTimeout(function() {
  try {
    noSuchVariable; // 이제 try..catch에서 에러를 핸들링 할 수 있다!
  } catch {
    alert( "에러를 잡았습니다!" );
  }
}, 1000);



Error객체 프로퍼티

name 에러객체 이름.
message 에러 상세내용을 담고 있는 문자열
stack 호출스택. 에러를 유발한 중첩 호출들의 순서정보


let json = '{"name":"John"}';

try {
  let user = JSON.parse(json);
  console.log( user.name );
} catch (error) {
  console.log( error );
}

서버로부터 받은 문자열이 JSON규칙에 따르지 않을때 JSON.parse함수가 에러를 던지는데 에러핸들링하지 않으면 스크립트는 중단된다.



에러개념의 폭을 넓혀보자.

try catch는 스크립트중단이라는 절박한상황을 대처하기위한 수단이지만 사용자의도에 벗어난 경우도 에러를 발생시키면 try catch구문으로 체계적인 에러처리가 가능하게 된다.

let json = '{ "name": "john" }';

try {
  let user = JSON.parse(json); // <-- 에러 없음
  alert( user.age ); // 나이가 없다
} catch (e) {
  alert( "실행되지 않습니다." );
}

서버로부터 json문자열이 문법에는 맞지만 age속성이 없어 사용자의도에 맞지않는 상황이 발생할 수 있다.


let json = '{"name":"John"}';

try {
  let user = JSON.parse(json);
  if( user.age == undefined ){
    throw new Error("no age");
  }
} catch (error) {  
  if( error.message == "no age" ){
    console.log( error.name, error.message );
  }
}

에러핸들링 순서

  1. 에러가 발생하는 코드를 try블럭으로 감싸고 처리하고자 하는 유형의 에러들이 발생되도록 에러객체를 세분화해서 throw해야 한다.

  2. catch블럭에서는 try블럭에서 분류된 에러들을 유형별로 처리하돌고 하고 지금 처리하지 못할 예외는 다시 외부로 넘긴다.

let json = '{ "age" : 30 , "name":"lee" }'; 
try {

  let user = JSON.parse(json);
  if (!user.name) {
    throw new SyntaxError("불완전한 데이터: 이름 없음");
  }

  blabla(); // 예상치 못한 에러
  console.log( user.name );

} catch (error) {

  if( error instanceof SyntaxError ){
    console.log( 'SyntaxError 발생 : ', error.name, error.message );
  }else{
    throw new Error("몰라에러");    
  }

}

catch블럭에서는 SyntaxError유형에 대해서만 처리하고 어떤 유형이 발생할지 모른다면 위와 같이 새로운 에러를 던지게 한다.

예상치못한 에러가 발생하면 스크립트가 중단되는것을 보고 외부에서 try catch블럭으로 처리하던지 에러유형에 대한 처리를 추가해야 한다.


위와 같은 에러핸들링방식은 try블럭과 catch블럭의 코드들이 많아져 가독성이 떨어지게 된다.
function readData() {
  let json = '{ "age": 30 }';

  try {
    blabla(); // 에러!
  } catch (e) {
    if (!(e instanceof SyntaxError)) {
      throw e; // 알 수 없는 에러 다시 던지기
    }
  }
}

try {
  readData();
} catch (e) {
  alert( "External catch got: " + e ); // 에러를 잡음
}

코드들을 블럭단위로 캡슐화하여 분리함으로써 가독성이 높아진다.



function func() {

  try {
    return 1;

  } catch (e) {
    /* ... */
  } finally {
    alert( 'finally' );
  }
}

finally블럭은 예외발생여부와 관계없이 반드시 처리된다.
위와같이 return문이 있어도 처리된후 return된다.

0개의 댓글