일반적으로 다른 언어에서도 사용하는 try..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' 바인딩
구식브라우저에선 폴리필이 필요함.
구체적이 에러 정보가 필요없으면 생략 가능
try {
// ...
} catch { // <-- (err) 없이 쓸 수 있음
// ...
}
'throw' 연산자
다른 언어와 동일한 문법과 동작 패턴..
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: 불완전한 데이터: 이름 없음
}
에러 다시 던지기
밖에서 에러를 처리하도록 하기 위함
예상한 에러가 아닐경우, 다시 처리하기위해서 던진다
let json = '{ "age": 30 }'; // 불완전한 데이터 , 아래에서 name을 호출하는데 , name key가 없음.
try {
let user = JSON.parse(json);
if (!user.name) {
throw new SyntaxError("불완전한 데이터: 이름 없음");
}
blabla(); // 예상치 못한 에러
alert( user.name );
} catch(e) {
//SyntaxError 만 처리할것임
if (e.name == "SyntaxError") {
alert( "JSON Error: " + e.message ); // name이 없었으니 여기가 실행됨.
} else {
throw e; // 에러 다시 던지기 (*), 밖에서 다시 잡아서 처리한다, 그렇지 않으면 종료됨.
}
}
try..catch..finally
역시 다른것들과 동일. try, catch 여부와 관계없이 finally는 항상 실행.
별개로, try..finally 를 사용가능한데, try..finally 안에선 에러를 처리하고 싶지 않지만, 시작한 프로세스가 마무리되었는지 확실히 하고 싶은 경우에 사용합니다.
setTimeout(() => {
console.log('This will still run.');
}, 500);
// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');
2. output
> Caught exception: ReferenceError: nonexistentFunc is not defined
> Exception origin: undefinedThis will still run.
3. conclusion
- uncaughtException Listener 등록해서, 프로세스 종료를 하지 않을 수 있었다.
- 등록하지 않았을때, output
nonexistentFunc();
^
ReferenceError: nonexistentFunc is not defined
at Object. (/Users/kgneng2/script/test.js:7:1)
at Module._compile (module.js:577:32)
at Object.Module._extensions..js (module.js:586:10)
at Module.load (module.js:494:32)
at tryModuleLoad (module.js:453:12)
at Function.Module._load (module.js:445:3)
at Module.runMain (module.js:611:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:160:9)
at bootstrap_node.js:507:3
- 브라우저에서는 [window.onerror](https://developer.mozilla.org/ko/docs/Web/API/GlobalEventHandlers/onerror)를 이용
```javascript
<script>
window.onerror = function(message, url, line, col, error) {
alert(`${message}\n At ${line}:${col} of ${url}`);
};
function readData() {
badFunc(); // 에러가 발생한 장소
}
readData();
</script>
에러 객체
선택적 'catch' 바인딩
'throw' 연산자
에러 다시 던지기
try..catch..finally
전역 catch
process.on("uncaughtException")
process.on('uncaughtException', (err, origin) => { fs.writeSync( process.stderr.fd,
Caught exception: ${err}\n
+Exception origin: ${origin}
); });setTimeout(() => { console.log('This will still run.'); }, 500);
// Intentionally cause an exception, but don't catch it. nonexistentFunc(); console.log('This will not run.');
nonexistentFunc(); ^
ReferenceError: nonexistentFunc is not defined at Object. (/Users/kgneng2/script/test.js:7:1)
at Module._compile (module.js:577:32)
at Object.Module._extensions..js (module.js:586:10)
at Module.load (module.js:494:32)
at tryModuleLoad (module.js:453:12)
at Function.Module._load (module.js:445:3)
at Module.runMain (module.js:611:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:160:9)
at bootstrap_node.js:507:3
message : 에러 메시지
url : 에러가 발생한 스크립트 URL
line, col : 에러가 발생한 곳의 줄과 열 번호
error : 에러 객체
스크립트 복구하려는 목적보다는 개발자에게 에러메시지 보내는 목적으로 사용한다.
에러메시지 상용 서비스