try catch
: 스크립트가 죽는 것을 방지하고 에러를 잡아 합당한 행위를 하도록 하는 문법
try {
// 코드...
} catch (err) {
// 에러 핸들링
}
- 동작 알고리즘
1. try 내의 코드가 실행
2. 에러가 없다면 try의 마지막 줄까지 실행하고 catch 블록은 생략
3. 에러가 있는 경우 try안 코드의 실행이 중단되고 catch 블록으로 제어흐름이 넘어감
catch 매개 변수의 err에 어떤 일이 일어났는지에 대한 에러객체가 포함되어 출력 됨
※ try catch는 오직 런타임 에러에만 동작함
※ try catch는 동기적으로 동작
try {
setTimeout(function() {
noSuchVariable; // 스크립트는 여기서 죽습니다.
}, 1000);
} catch (e) {
alert( "작동 멈춤" );
}
setTimeout(function() {
try {
noSuchVariable; // 이제 try..catch에서 에러를 핸들링 할 수 있습니다!
} catch {
alert( "에러를 잡았습니다!" );
}
}, 1000);
에러 객체
: 에러가 발생하면 자바스크립트는 에러 상세내용이 담긴 객체를 생성하고
catch 블록에 객체를 인수로 전달
- 에러 객체의 주요 프로퍼티
: name (에러의 이름)
: message (에러 상세 내용을 담고 있는 메시지)
: stack (현재 호출 스택 / 에러를 유발한 중첩 호출들의 순서 정보를 가진 문자열 / 디버깅 목적)
선택적 catch 바인딩
: 에러에 대한 자세한 정보가 필요하지 않으면 catch에서 생략 가능
try {
// ...
} catch { // <-- (err) 없이 쓸 수 있음
// ...
}
직접 에러를 만들어서 던지기
- throw 연산자
: 에러를 생성하는 연산자
: throw <error object> 숫자, 문자열과 같은 원시형 자료를 포함한 어떤 것이든 에러 객체로 사용할 수 있음
: 내장 에러와의 호환을 위해 name과 message 프로퍼티를 넣는 것을 권장
- 자바스크립트가 지원하는 표준 에러 객체 관련 생성자
: Error
: SyntaxError
: ReferenceError
: TypeError
let error = new Error("이상한 일이 발생했습니다. o_O");
alert(error.name); // Error
alert(error.message); // 이상한 일이 발생했습니다. o_O
try {
JSON.parse("{ 잘못된 형식의 json o_O }");
} catch(e) {
alert(e.name); // SyntaxError
alert(e.message); // Unexpected token b in JSON at position 2
}
let json = '{ "age": 30 }'; // 불완전한 데이터
try {
let user = JSON.parse(json); // <-- 에러 없음
if (!user.name) {
throw new SyntaxError("불완전한 데이터: 이름 없음"); // (*)
}
alert( user.name );
} catch(e) {
alert( "JSON Error: " + e.message ); // JSON Error: 불완전한 데이터: 이름 없음
}
에러 다시 던지기
: 예기치 못한 에러가 try 블록에서 발생할 경우 디버깅을 위한 방법
: catch 블록 안에서 에러 객체를 분석하여 분기
let json = '{ "age": 30 }'; // 불완전한 데이터
try {
let user = JSON.parse(json);
if (!user.name) {
throw new SyntaxError("불완전한 데이터: 이름 없음");
}
blabla(); // 예상치 못한 에러
alert( user.name );
} catch(e) {
if (e instanceof SyntaxError) {
alert( "JSON Error: " + e.message );
} else {
throw e; // 에러 다시 던지기 (*)
}
}
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 ); // 에러를 잡음
}
try catch finally
: try catch 실행이 끝나고 반드시 실행해야하는 코드를 넣는 문법
try {
... 코드를 실행 ...
} catch(e) {
... 에러 핸들링 ...
} finally {
... 항상 실행 ...
}
try {
alert( 'try 블록 시작' );
if (confirm('에러를 만드시겠습니까?')) 이상한_코드();
} catch (e) {
alert( 'catch' );
} finally {
alert( 'finally' );
}
let num = +prompt("양의 정수를 입력해주세요.", 35)
let diff, result;
function fib(n) {
if (n < 0 || Math.trunc(n) != n) {
throw new Error("음수나 정수가 아닌 값은 처리할 수 없습니다.");
}
return n <= 1 ? n : fib(n - 1) + fib(n - 2);
}
let start = Date.now();
try {
result = fib(num);
} catch (e) {
result = 0;
} finally {
diff = Date.now() - start;
}
alert(result || "에러 발생");
alert( `연산 시간: ${diff}ms` );
※ finally 절은 try catch 절을 빠져나가는 어떤 경우에도 실행됨
function func() {
try {
return 1;
} catch (e) {
/* ... */
} finally {
alert( 'finally' );
}
}
alert( func() ); // finally 안의 alert가 실행되고 난 후, 실행됨
전역 catch
: try catch 바깥에서 발생한 치명적인 에러로 인해 스크립트가 죽지 않도록 하는 문법
: 브라우저에서는 window / nodeJs 환경에서는 global
window.onerror = function(message, url, line, col, error) {
// ...
};
- message
: 에러 메시지
- url
: 에러가 발생한 스크립트의 url
- line, col
: 에러가 발생한 곳의 줄과 열 번호
- error
: 에러 객체
<script>
window.onerror = function(message, url, line, col, error) {
alert(`${message}\n At ${line}:${col} of ${url}`);
};
function readData() {
badFunc(); // 에러가 발생한 장소
}
readData();
</script>
※ window.onerror는 개발자에게 에러 메시지를 보내는 용도로 사용
Refference
'Programming > JavaScript' 카테고리의 다른 글
모던 자바스크립트 (promise와 async, await) 9-1. 콜백 / 프라미스 (0) | 2022.04.23 |
---|---|
모던 자바스크립트 (에러핸들링) 8-2. 커스텀 에러와 에러 확장 (0) | 2022.04.23 |
모던 자바스크립트 (클래스) 7-3. 내장 클래스 확장하기 / instanceof 로 클래스 확인 하기 / 믹스인 (0) | 2022.04.23 |
모던 자바스크립트 (클래스) 7-2. 정적 메서드와 정적 프로퍼티 / private, protected 프로퍼티와 메서드 (0) | 2022.04.23 |
모던 자바스크립트 (클래스) 7-1. 클래스 기본 문법 / 클래스 상속 (0) | 2022.04.23 |