[혼공자스] 08. 예외처리
오류의 종류
구문오류 syntax error | 예외 exception 또는 런타임 오류 runtime error |
프로그램 실행 전 발생오류 코드가 실행조차 되지 않는 오류 괄호의 짝을 맞추지 않았을 경우 문자열을 여닫지 않았을 경우 |
프로그램 실행 중 발생오류 문법적 오류를 제외하고 코드 실행 중간에 발생하는 오류 SyntaxError 라고 출력되는 오류 이외의 모든 오류 (TypeError, ReferenceError, RangeError)가 예외로 분류. |
기본 예외 처리 " 조건문을 사용해서 예외가 발생할 수 있는 경우와 아닌 경우를 나눠서 처리하는 것 "
querySelector( ) 메소드로 추출된 문서 객체가 없는 경우
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
</body>
<script>
document.addEventListener('DOMContentLoaded', () => {
const h1 = document.querySelector('h1')
h1.textContent = '안녕하세요'
})
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
</body>
<script>
document.addEventListener('DOMContentLoaded', () => {
const h1 = document.querySelector('h1')
if (h1) { //h1이 존재하면 true로 변환되고 존재하지 않으면 false로 변환됨.
h1.textContent = '안녕하세요'
} else {
console.log('h1 태그를 추출할 수 없음')
}
})
</script>
</html>
고급 예외 처리 " try catch finally구문 이용하여 예외처리 "
try {
//예외가 발생할 가능성이 있는 코드
} catch (exception) {
//예외가 발생했을 때 실행할 코드
} finally {
//무조건 실행할 코드 //finally 구문은 필요한 경우에만 사용.
}
조건문 처럼 try 구문안에서 예외를 발생하면 이를 catch구문에서 처리. finally구문은 필수사항은 아니며 예외 발생 여부와상관없이 수행해야하는 작업이 있을 때 사용.
다음 코드는 변수 자체가 존재하지 않는데, 존재하지않는 변수의 메소드를 사용하는 코드임. 따라서 프로그램은 예외를 발생해서 종료하는데
//try catch 구문의 사용
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
try {
willExcept.byeBye()
console.log("try 구문의 마지막 줄")
} catch (exception) {
console.log("catch 구문의 마지막 줄")
}
</script>
</head>
<body>
</body>
</html>
//finally 구문
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
try {
willExcept.byeBye()
console.log("try 구문의 마지막 줄")
} catch (exception) {
console.log("catch 구문의 마지막 줄")
} finally {
console.log("finally 구문의 마지막 줄") //예외 발생 여부와 상관업이 무조건 실행.
}
</script>
</head>
<body>
</body>
</html>
//예외 처리 구문 내부에서 return 사용하기(1)
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
function test () {
try {
alert('A위치임')
throw "예외 강제 발생" //throw키워드로 예외를 강제로 발생시킴
} catch (exception) {
alert('B위치임')
return
}
alert('C위치임')
}
//함수를 호출
test()
</script>
</head>
<body>
</body>
</html>
//예외 처리 구문 내부에서 return 사용하기 (2)
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
function test () {
try {
alert('A위치임')
throw "예외 강제 발생"
} catch (exception) {
alert('B위치임')
return
} finally {
alert('C위치임')
}
}
//함수를 호출
test()
</script>
</head>
<body>
</body>
</html>
예외 처리 고급
예외가 발생하면 예외와 발생된 정보를 확인 가능한데 이러한 정보를 확인할 수 있게 해주는 것이 예외 객체 exception object임.
예외를 강제로 발생시킬 때 throw키워드 사용
예외 객체 " try catch 구문을 사용할 때 catch의 괄호 안에 입력하는 식별자 "
일반적으로 e 나 exception이라는 식별자 사용
try {
} catch (exception) { // exception : 예외 객체
}
속성 이름 | 설명 |
name | 예외 이름 |
message | 예외 메시지 |
//예외 정보 출력하기
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
try {
const array = new Array(999999999999999)
} catch (exception) {
console.log(exception)
console.log()
console.log(`예외 이름: ${exception.name}`)
console.log(`예외 메시지: ${exception.message}`)
}
</script>
</head>
<body>
</body>
</html>
예외 강제 발생 " throw 키워드 사용 "
//단순하게 예외를 발생
throw 문자열
//조금 더 자세하게 예외 발생
throw new Error (문자열)
콘솔에서 throw를 쓰면 당연하게도 곧바로 예외를 발생시킴.
throw 구문을 사용하는 예제. divide( ) 함수를 만든 예시. 함수 내부에는 0으로 나눌 때 ' 0으로는 나눌 수 없음'라는 오류를 발생하도록 작성.
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
function divide (a, b) {
if (b === 0) {
throw '0으로는 나눌 수 없음'
}
return a / b
}
console.log(divide(10, 2))
console.log(divide(10, 0))
</script>
</head>
<body>
</body>
</html>
//예외를 강제로 발생시키기
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
function test(object) {
console.log(object.a + object.b)
}
test({})
</script>
</head>
<body>
</body>
</html>
일반적인 프로그래밍 언어라면 object 객체에 a 속성과 b 속성이 없으므로 예외를 발생할 것이고, 존재하지 않는 것을 더하므로 object.a + object.b를 할 때도 예외를 발생한다. 그러면 사용자는 자신이 잘못 사용했다는 걸 인지하고 수정가능함.
하지만 자바스크립트는 object.a가 undefined로 나오며, object.b도 undefined로 나옵니다. 여기에서 undefined + undefined를 하면 NaN이 나옴. 결국 아무 오류 없이 코드가 정상적으로 실행됨.
자바스크립트는 undefined와 NaN이라는 값이 있어서 다른 프로그래밍 언어에 비해서 예외를 많이 발생시키지 않음. 고로 사용자에게 함수를 잘못 사용했다는 것을 강제로라도 인지시켜줄 필요가 있는 것.
//예외를 강제로 발생시켜서 사용 유도하기
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
function test (object) {
if (object.a !== undefined && object.b !== undefined) {
console.log(object.a + object.b)
} else {
throw new Error("a속성과 b속성을 지정하지 않았음")
}
}
test({})
</script>
</head>
<body>
</body>
</html>