try {
// 코드
} catch (err) {
// 에러 핸들링
}
try {...}
내의 코드가 실행된다try
내 마지막 줄 까지 실행되고 catch
는 건너뛴다try
내 코드 실행이 중단되고, catch(err)
블록으로 제어 흐름이 넘어간다err
(아무 이름이나 OK)는 무슨 일이 일어났는지에 대한 설명이 담긴 에러 객체를 포함한다try..catch
는 실행 가능한 코드 = 유효한 코드에서 발생하는 에러만 처리할 수 있다
👉 이를 런타임 에러 혹은 예외 라고 부른다
중괄호 짝이 안 맞는 것 처럼 문법오류가 있을 경우엔 try..catch
가 동작하지 않는다
try {
} catch(e) {
alert('여기 동작 X');
}
자바스크립트 엔진은 코드를 읽고 난 후 코드를 실행한다
코드를 읽다가 발생한 에러는 parse-time 에러라고 하는데, 엔진은 이 코드를 이해할 수 없기 때문에 parse-time 에러는 코드 안에서 복구가 불가능하다
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
}
스펙에 추가된 지 얼마 안됐으므로 구식 브라우저는 폴리필 필수
try {
// ...
} catch { // <- (Err) 없이 사용가능
// ...
}
에러에 대한 자세한 정보가 필요하지 않다면, 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
연산자는 에러를 생성한다
이론적으로는 숫자, 문자열 같은 원시형 자료를 포함한 어떤 것이든 에러 객체로 사용할 수 있지만 내장 에러와의 호환을 위해 되도록 에러 객체에 name
과 message
프로퍼티를 넣어주는 것을 권장한다
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
의 값은 인수에서 가져온다