console.log('[Start]');
foo(); // ReferenceError: foo is not defined
// 발생한 에러를 방치하면 프로그램은 강제 종료된다.
// 에러에 의해 프로그램이 강제 종료되어 아래 코드는 실행되지 않는다.
console.log('[End]');
이러한 에러에 대처하기 위해 try...catch 문 사용!
console.log('[Start]');
try {
foo();
} catch (error) {
console.error('[에러 발생]', error);
// [에러 발생] ReferenceError: foo is not defined
}
// 발생한 에러에 적절한 대응을 하면 프로그램이 강제 종료되지 않는다.
console.log('[End]');
// DOM에 button 요소가 존재하지 않으면 querySelector 메서드는 에러를 발생시키지 않고 null을 반환한다.
const $button = document.querySelector('button'); // null
$button.classList.add('disabled');
// TypeError: Cannot read property 'classList' of null
console.log('[Start]');
try {
// 실행할 코드(에러가 발생할 가능성이 있는 코드)
foo();
} catch (err) {
// try 코드 블록에서 에러가 발생하면 이 코드 블록의 코드가 실행된다.
// err에는 try 코드 블록에서 발생한 Error 객체가 전달된다.
console.error(err); // ReferenceError: foo is not defined
} finally {
// 에러 발생과 상관없이 반드시 한 번 실행된다.
console.log('finally');
}
// try...catch...finally 문으로 에러를 처리하면 프로그램이 강제 종료되지 않는다.
console.log('[End]');
const error = new Error("Error!!");
Error: Error!!
at <anonymous>:1:15
message: "Error!!"
stack: "Error: Error!!\n at <anonymous>:1:15"
[[Prototype]]
: Object
const error2 = new TypeError("hh")
TypeError: hh
at <anonymous>:1:16
message: "hh"
stack: "TypeError: hh\n at <anonymous>:1:16"
try {
if(true) throw new Error("something wrong");
} catch (error) {
console.log(error);
}
const foo = () => {
throw Error('foo에서 발생한 에러'); // ④
};
const bar = () => {
foo(); // ③
};
const baz = () => {
bar(); // ②
};
try {
baz(); // ①
} catch (err) {
console.error(err);
}
foo(에러발생) -> bar로 전파 -> baz로 전파 -> 전역에서 error가 캐치 됨.
throw된 에러를 캐치하지 않으면 호출자 방향으로 전파됨.
이 때 throw된 에러를 캐치하여 적절히 대응하면 프로그램을 강제 종료하지 않고 코드의 실행 흐름을 복구 가능
throw된 에러를 어디서도 캐치하지 않으면 강종!
주의!
비동기함수인 setTimeout 또는 프로미스의 후속 처리 메서드의 콜백 함수는 호출자가 없다.
즉, 콜스택이 비었을 때 이벤트 루프에 의해 콜스택으로 푸쉬되어 실행되고 콜백함수의 실행 컨텍스트는 콜 스택의 가장 하부에 존재하여 에러를 전파할 호출자가 존재하지 않음.