try..catch와 에러 핸들링

100pearlcent·2021년 9월 27일
1

JavaScript

목록 보기
16/22
post-thumbnail

try..catch

try {
	// 코드
} catch (err) {
	// 에러 핸들링
}
  1. try {...}내의 코드가 실행된다
  2. 에러가 없다면 ➡️ try 내 마지막 줄 까지 실행되고 catch는 건너뛴다
  3. 에러가 있다면 ➡️ try 내 코드 실행이 중단되고, catch(err) 블록으로 제어 흐름이 넘어간다
    변수 err(아무 이름이나 OK)는 무슨 일이 일어났는지에 대한 설명이 담긴 에러 객체를 포함한다



try..catch는 런타임 에러에만 동작한다

try..catch는 실행 가능한 코드 = 유효한 코드에서 발생하는 에러만 처리할 수 있다
👉 이를 런타임 에러 혹은 예외 라고 부른다

중괄호 짝이 안 맞는 것 처럼 문법오류가 있을 경우엔 try..catch가 동작하지 않는다

try {
} catch(e) {
  alert('여기 동작 X');
}

자바스크립트 엔진은 코드를 읽고 난 후 코드를 실행한다
코드를 읽다가 발생한 에러는 parse-time 에러라고 하는데, 엔진은 이 코드를 이해할 수 없기 때문에 parse-time 에러는 코드 안에서 복구가 불가능하다



try..catch는 동기적으로 동작한다

try {
	setTimeout(function() {
    	noSuchVariable; // Script dies here
    }, 1000);
} catch (e) {
	alert('끝');
}

setTimeOut처럼 스케줄 된(scheduled) 코드에서 발생한 예외는 try...catch에서 잡아낼 수 없다

➡️setTimeOut에 넘겨진 익명 함수는 엔진이 try..catch를 떠난 다음에서야 실행되기 때문이다

setTimeout(function() {
  try {
    noSuchVariable; // 에러 핸들링 가능
  } catch {
    alert( "에러를 잡았습니다!" );
  }
}, 1000);

스케줄 된 함수 내부의 예외를 잡으려면, try..catch를 반드시 함수 내부에 구현해야 한다



에러 객체

에러가 발생하면 자바스크립트는 에러 상세내용이 담긴 객체를 생성한다
그 후, catch 블록에 이 객체를 인수로 전달한다

try {
	// ...
} catch(err) { // <- '에러 객체'
	// ...
}

내장 에러 전체와 에러 객체는 두 가지 주요 프로퍼티를 가진다

  • name : 에러 이름
    e.g.) 정의되지 않은 변수 때문에 발생한 에러라면 "ReferenceError"가 이름이 된다

  • message : 에러 상세 내용을 담고 있는 문자 메시지

이 둘 외에 대부분의 호스트 환경에서 지원하는 비표준 프로퍼티도 존재한다
stack이 가장 널리 사용되는 비표준 프로퍼티에 해당한다

  • stack : 현재 호출 스택. 에러를 유발한 중첩 호출들의 순서 정보를 가진 문자열로 디버깅 목적으로 사용한다
try {
  lalala; // 변수가 정의되지 않았으므로 에러
} catch(err) {
  alert(err.name); // ReferenceError
  alert(err.message); // lalala is not defined
  alert(err.stack); // ReferenceError: lalala is not defined at ... (호출 스택)

  // 에러 전체를 보여줄 수 있다
  // 이때, 에러 객체는 "name: message" 형태의 문자열로 변환
  alert(err); // ReferenceError: lalala is not defined
}



선택적 catch 바인딩

스펙에 추가된 지 얼마 안됐으므로 구식 브라우저는 폴리필 필수

try {
	// ...
} catch { // <- (Err) 없이 사용가능
	// ...
}

에러에 대한 자세한 정보가 필요하지 않다면, catch에서 이를 생략할 수 있다



try..catch 사용하기

잘못된 형식의 JSON이 들어와서 JSON.parse가 에러를 만들어서 스크립트가 죽는 경우를 가정하고 이를 try..catch를 사용해 이를 처리하자

let json = '{ bad json }'

try {
	let user = JSON.parse(json); // 여기서 에러 발생
  	alert(user.name); // 이 줄은 동작하지 않음
} catch (e) {
	// 에러 발생했으므로 제어 흐름이 catch 문으로 넘어온다
  	alert('재요청을 시도합니다');
  	alert(e.name);
  	alert(e.message);
}

물론 catch블록 안에서 새로운 네트워크 요청 보내기, 사용자에게 대안 제안하기, 로깅장치에 에러 정보 보내기 등과 같은 일을 할 수도 있다



직접 에러를 만들어 던지기

throw <error object>

throw 연산자는 에러를 생성한다

이론적으로는 숫자, 문자열 같은 원시형 자료를 포함한 어떤 것이든 에러 객체로 사용할 수 있지만 내장 에러와의 호환을 위해 되도록 에러 객체에 namemessage 프로퍼티를 넣어주는 것을 권장한다

let error = new Error(message);
let error = new SyntaxError(message);
let error = new ReferenceError(message);

자바스크립트가 제공하는 Error, SyntaxError, ReferenceError, TypeError 등의 표준 에러 객체 관련 생성자를 이용해 에러 객체를 만들 수도 있다

let error = new Error('에러가 발생했어요');

alert(error.name); // Error
alert(error.message); // 에러가 발생했어요

일반 객체가 아닌 내장 생성자를 사용해 만든 내장 에러 객체의 name 프로퍼티는 생성자 이름과 동일한 값을 갖는다
프로퍼티 message의 값은 인수에서 가져온다

0개의 댓글