에러가 일어났을 때 스크립트가 중단되는 것을 막기 위해, 에러를 잡는 기능을 하는 try...catch문을 사용하면 try...catch문 안에서 에러가 처리되어 스크립트가 중지되지 않음!
단, try...catch문은 런타임 에러에만 동작!
(유효한 자바스크립트 코드에만 실행된다는 의미. 만약 문법적 문제가 있는 경우엔 try...catch문이 동작되지 않는다.)
기본 문법
try {
// 코드...
} catch (err) {
// 에러 핸들링
}
타이머를 사용하는 scheduled코드에서 발생한 예외는, 코드가 try...catch를 떠난 후에 실행되므로 확인불가.
스케줄 된 함수 내부의 예외를 잡기 위해서는, 스케줄 된 함수 내부에 try...catch를 구현해야 한다.
etTimeout(function() {
try {
noSuchVariable; // 이제 try..catch에서 에러를 핸들링 할 수 있습니다!
} catch {
alert( "에러를 잡았습니다!" );
}
}, 1000);
에러 객체
에러가 발생하면 자바스크립트는 에러 상세내용이 담긴 객체를 생성해, catch 블록에 인자로 전달한다.
에러는 에러 이름(name), message(에러 상세 내용), 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'바인딩
*** 최근에 추가된 문법. (폴리필 필요할 수 있음)
에러에 대한 자세한 정보가 필요하지 않으면 catch에서 '(err)'없이 생략하여 쓸 수 있다.
try {
// ...
} catch { // <-- (err) 없이 쓸 수 있음
// ...
}
'try...catch'사용하기
실무 사용 예) JSON.parse 메서드를 통해 받은 json 형식이 잘못되어 에러가 발생할 경우, 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 );
}
직접 에러를 만들어 Throw 하기.
- Throw 연산자
throw <error object>
발생한 에러 종류를 찾아-> throw연산자를 사용해 에러 던지기
try {
JSON.parse("{ 잘못된 형식의 json o_O }");
} catch(e) {
alert(e.name); // SyntaxError
alert(e.message); // Unexpected token b in JSON at position 2
}
=> SyntaxError가 발생하는 것 확인함.
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: 불완전한 데이터: 이름 없음
}
=> user.name 이 존재하지 않으므로 SyntaxError가 throw 된다.
단, 이경우 어떤 에러가 나던 "JSON Error: " 부분은 출력되게 된다.
이를 해결하기 위한 방법은 바로, 에러를 다시 던져주는 것!
에러 다시 던지기 'Error Rethrowing'
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; // 에러 다시 던지기 (*)
}
}
// 위와 같이 rethrowing을 할 경우, 발생한 에러가 SyntaxError가 아니면 "JSON Error: " 문자열은 출력되지 않음.
하지만 다시 던져진 에러는, 위의 try..catch문 밖으로 던져진다.
때문에, 이를 처리할 외부 try..catch문을 써주지 않으면 스크립트가 중단될 수 있다.
외부로 rethrowing된 에러 처리하기.
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 ); // 에러를 잡음
}
이 시점에서 작성한 코드는, 어떤 에러던지 스크립트 중지 없이 실행 가능하다.
- finally 구문.
try {
... 코드를 실행 ...
} catch(e) {
... 에러 핸들링 ...
} finally {
... 항상 실행 ...
}
Node.js의 process.on("uncaughtException") 이나,
브라우저 환경의 window.onerror를 이용해, 예상치 못한 에러가 발생했을 때 이 함수가 실행되게 할 수 있다.
보통 개발자에게 에러 메시지를 보낼 때 사용됨.
//--문법--
window.onerror = function(message, 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>
직관성을 위해 에러 클래스를 만들어 사용하면 직관성을 키울 수 있다.
https://ko.javascript.info/custom-errors
javascript.info - 프라미스와 async, await(2) (0) | 2023.01.02 |
---|---|
javascript.info - 프라미스와 async, await (0) | 2023.01.02 |
javascript.info - 9.클래스 (0) | 2022.12.30 |
javascript.info - 프로토타입과 프로토타입 상속 (0) | 2022.12.30 |
javascript.info - 객체 프로퍼티 설정 (0) | 2022.12.30 |