47.1 에러 처리의 필요성
- 에러(error)가 발생하지 앟는 코드를 작성하는 것은 불가능. 따라서 에러는 언제나 발생 가능
- 발생한 에러에 대해 대처하지 않고 방치하면 프로그램은 강제 종료됨
- 직접적으로 에러를 발생하지는 않는 예외(exception)적인 상황이 발생할 수 도 있음. 예외적인 상황에 적절하게 대응하지 않으면 에러로 이어질 가능성이 큼
//DOM에 button 요소가 존재하지 않으면 querySelector 메서드는 에러를 발생시키지 않고 null을 반환
const $butoon = document.querySelector('button'); //null
$button.classList.add('disabled');
//TypeError: Cnnot read property 'classList' of null
- 우리가 작성한 코드에서는 언제나 에러나 예외적인 상황이 발생할 수 있다는 것을 전제하고 이에 대응하는 코드를 작성하는 것이 중요
47.2 try...catch ... finally문
예외 처리 방법
1) querySelector나 Array#find메서드처럼 예외적인 상황이 발생하면 반환하는 값(null 또는 -1)을 if 문이나 단축 평가 또는 옵셔널 체이닝 연산자를 통해 확인해서 처리하는 방법
2) 예외 처리 코드를 미리 등록해두고 에러가 처리하면 에러 처리 코드로 점프하도록 하는 방법
= try...catch...finally문
try...catch...finally문
- try...catch...finally문으로 에러를 처리하면 프로그램이 강제 종료되지 않음
try {
//실행할 코드 (에러가 발생할 가능성이 있는 코드)
}catch(err) {
//try 코드 블록에서 에러가 발생하면 이 코드 블록의 코드가 실행
//err에는 try 코드 블록에서 발생한 Error 객체가 전달됨
} finally {
//에러 발생과 상관없이 반드시 한 번 실행
}
- 먼저 try 코드 블록이 실행. 이떄 try 코드 블록에 포함된 문 중에서 에러가 발생하면 발생한 에러는 catch문의 err 변수에 전달되고 catch 코드 블록이 실행
- catch문의 err 변수는 try 코드 블록에 포함된 문 중에서 에러가 발생하면 생성되고 catch 코드 블록에서만 유효
- finally 코드 블록은 에러 발생과 상관없이 반드시 한 번만 실행
47.3 Error 객체
- Error 생성자 함수는 에러 객체를 생성
- Error 생성자 함수에는 에러를 상세히 설명하는 에러 메시지를 인수로 전달 가능
const error = new Error('invalid');
- 에러 객체는 message 프로퍼티와 stack 프로퍼티를 가짐
1) message 프로퍼티
: Error 생성자 함수에 인수로 전달한 에러 메시지
2) stack 프로퍼티
: 에러를 발생시킨 콜스택의 호출 정보를 나타내는 문자열이며 디버깅 목적으로 상ㅇ
- 자바스크립트는 7가지의 에러 객체를 생성할 수 있는 Error 생성자 함수 제공
- 모두 Error.prototype을 상속 받음
생성자 함수 | 인스턴스 |
Error | 일반적 에러 객체 |
SyntaxError | 자바스크립트 문법에 맞지 않는 문을 해석할 떄 발생하는 에러 객체 |
ReferenceError | 참조할 수 없는 식별자를 참조했을 때 발생하는 에러 객체 |
TypeError | 피연산자 또는 인수의 데이터 타입이 유효하지 않을 때 발생하는 에러 객체 |
RangeError | 숫자값의 허용 범위를 벗어났을 때 발생하는 에러 객체 |
URIError | encodeURI 또는 decodeURI 함수에 부적절한 인수를 전달했을 떄 발생하는 에러 객체 |
EvalError | eval 함수에서 발생하는 에러 객체 |
47.4 thorw 문
- Error 생성자 함수로 에러 객체를 생성한다고 에러가 발생하는 것은 아님
- 에러를 발생시키려면 try 코드 블록에서 thorw문으로 에러 객체를 던져야 함
throw 표현식;
- 에러를 던지면 catch문의 에러 변수가 생성되고 던져진 에러 객체가 할당. 그리고 catch 코드 블록이 실행되기 시작
try {
//에러 객체를 던지면 catch 코드 블록이 실행되기 시작
thorw new Error('something wrong');
} catch(error) {
console.log(error);
}
ex)
- 외부에서 전달받은 콜백 함수를 n번만큼 반복 호출하는 repeat 함수
- repeat 함수는 두 번쨰 인수로 반드시 콜백함수를 전달받아야 함
//외부에서 전달받은 콜백 함수를 n번만큼 반복 호출
const repeat = (n,f) => {
//매개 변수 f에 전달한 인수가 함수가 아니면 TypeError를 발생
if(typeof f !== 'function') throw new TypeError('f must b a function');
for(var i = 0; i < n; i++) {
f(i); //i를 전달하면서 f를 호출
}
};
try {
repeat(2,1); //두 번째 인수가 함수가 아니므로 TypeError가 발생(throw)
} catch(err) {
console.error(err); //TypeError: f must b a function
}
47.5 에러의 전파
- 에러는 호출자(caller) 방향으로 전파
- 콜 스택의 아래 방향(실행 중인 실행 컨텍스트가 푸시되기 직전에 푸시된 실행 컨텍스트 방향)으로 전파
const foo = () => {
throw Error('foo에서 발생한 에러');
};
const bar = () => {
foo();
};
const baz = () => {
bar();
};
try {
baz();
} catch(err) {
console.error(err);
}
- baz 함수를 호출하면 bar 함수가 호출되고 그 다음 foo 함수가 호출되고 foo 함수는 에러를 throw함
- foo 함수가 thorw한 에러는 호출자에게 전파되어 전역에서 캐치
- throw된 에러를 캐치하지 않으면 호출자 방향으로 전파. throw된 에러를 캐치하여 적절히 대응하면 프로그램을 강제 종료시키지 않고 코드의 실행 흐름을 복구할 수 있음. throw된 에러를 어디에서도 캐치하지 않으면 프로그램은 강제 종료됨
'JavaScript' 카테고리의 다른 글
[Deep dive] 49장 Babel과 Webpack을 이용한 ES6+/ES.NEXT 개발 환경 구축 (0) | 2023.08.25 |
---|---|
[Deep dive] 48장 모듈 (0) | 2023.08.25 |
[Deep dive] 46장 제너레이터와 async/await (0) | 2023.08.24 |
[Deep dive] 45장 프로미스 (0) | 2023.08.24 |
[Deep dive] 44장 REST API (0) | 2023.08.23 |