[JavaScript] 예외처리(Exception Handling)
태그: javascript · Error · SyntaxError · ReferenceError · RangeError · TypeError · URIError · EvalError · InternalError · try · catch · finally · throw
1. Error
런타임
오류가 발생했을 때 던져짐
1) 프로그래밍의 에러 3가지
(1). 문법 에러 : 문법상 맞지 않아서 발생하는 에러 (컴파일 시 에러가 있다고 알려줌)
(2). 런타임 에러 : 문법은 어긋나지 않지만 실행시에 오류가 발생. (존재하지 않는 메소드를 호출)
(3). 논리적 에러 : 문법적으로도 맞고 실행시에 아무런 문제가 발생하지 않지만 원하는 값이 안나오는 에러(로직이 잘못되어서 발생하는 에러)
2) Error types
(1) SyntaxError: 문법적으로 유효하지 않은 코드를 해석하려고 시도할 때 발생하는 오류를 의미
[SyntaxError - JavaScript | MDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError) |
에러발생이유
- 문법적으로 유효하지 않은 코드 사용
(2) ReferenceError : 현재 범위에서 존재하지 않거나 초기화되지 않은 변수를 참조했을 때 발생
[ReferenceError - JavaScript | MDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError) |
에러발생이유
(3) RangeError : 어떤 값이 집합에 없거나 허용되는 범위가 아닐 때 오류
[RangeError - JavaScript | MDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/RangeError) |
에러발생이유
- 허용되는 문자열이 아닌 값을 String.prototype.normalize() 에 전달 할때
- Array 생성자를 통해 잘못된 길이의 배열을 만드려고 시도 할때
- 숫자 메서드 Number.prototype.toExponential() Number.prototype.toFixed()
혹은
Number.prototype.toPrecision()에 나쁜 값을 전달 할때
(4) TypeError : 일반적으로 값이 기대하던 자료형이 아니라서 연산을 할 수 없을 때 발생하는 오류
[TypeError - JavaScript | MDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/TypeError) |
에러발생이유
- 함수에 전달된 피연산자 또는 인수가 해당 연산자나 함수가 예상하는 타입과 호환되지 않을 경우
- 변경할 수 없는 값을 수정하려고 할 경우
- 부적절한 방법으로 값을 사용하려고 할 경우
(5) URIError: URIError
객체는 전역 URI 핸들링 함수가 잘못된 방식으로 사용되었을 때의 오류를 표현함.
[URIError - JavaScript | MDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/URIError) |
에러발생이유
- encodeURI()나 decodeURl() 함수에 부적절한 매개변수를 제공했을 때 발생하는 오류의 인스턴스를 생성합니다.
(6) EvalError: 전역 eval() 함수에 관한 오류
[EvalError - JavaScript | MDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/EvalError) |
JavaScript에 의해 더 이상 발생하지 않지만 EvalError
객체는 하위 호환성을 위해 남아있습니다.
(7) InternalError: JavaScript 엔진 내부에서 발생한 오류
비표준: 이 기능은 비표준이므로 실제 프로덕션에서 사용하지 마세요. 모든 사용자 환경에서 작동하지 않을 수 도 있으며, 미래에 호환성 문제가 생길 수 있습니다.
[EvalError - JavaScript | MDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/EvalError) |
에러발생이유
- “too many switch cases”, (swich case의 수가 너무 많음)
- “too many parentheses in regular expression”, (정규표현식에 너무 많은 괄호가 있음)
- “array initializer too large”, (배열 초기화 값이 너무 큼)
- “too much recursion”. (너무 많은 재귀 호출)
3) Error Name Values 정리
종류 | 설명 |
---|---|
SyntaxError | 문법에러 , 코딩상의 실이므로 수정하지 않으면 프로그램이 동작하지 않음 |
ReferenceError | 잘못된 참조가 발생 |
RangeError | 숫자에서 범위를 벗어나면 오류가 발생 |
TypeError | 값 유형에 대한 오류가 발생 |
URIError | encodeURI( ) |
에서 오류가 발생 | |
EvalError | eval( )함수에서 오류가 발생 |
** eval( ) : 문자열을 코드로 변경해주는 함수 (최신 버전에서는 발생하지않음) | |
InternalError | 일반적으로 어떤 값이 너무 큰 경우 |
2. Exception Handling(예외 처리)
1) 기본 예외 처리
존재하면 true로 변환 , 존재하지 않으면 false로 변환
- 기본 활용
/* true */
{
function errHandler(){
const h1 = '인사';
if(h1==='인사'){
console.log('안녕하세요') // if 조건문을 사용하여 h1이 존재하면 true로 변환 , 존재하지 않으면 false로 변환
}else{
console.log('인사가 아니라 추출하지 않음.')
}
}
errHandler()
}
=> 결과값
[Running] node "/workspaces/codespaces-blank/index.js"
인사가 아니라 추출하지 않음.
[Done] exited with code=0 in 0.067 seconds
------------------------------------------------------------------
/* false */
{
function errHandler(){
const h1 = '인사가 아닐때';
if(h1==='인사'){
console.log('안녕하세요') // if 조건문을 사용하여 h1이 존재하면 true로 변환 , 존재하지 않으면 false로 변환
}else{
console.log('인사가 아니라 추출하지 않음.')
}
}
errHandler()
}
=> 결과값
[Running] node "/workspaces/codespaces-blank/index.js"
안녕하세요
[Done] exited with code=0 in 0.054 seconds
2) 고급 예외 처리
(1) try…catch…finally : try...catch
문은 실행할 코드블럭을 표시하고 예외(exception)가 발생(throw)할 경우의 응답을 지정
- 기본 문법
try {
예외가 발생할 가능성이 있는 코드
}catch(exception){
예외가 발생했을때 실행 할 코드
}finally{
무조건 실행할 코드(finally 구문은 필요한 경우에만 사용)
}
- try…catch…finally 활용
{
/* 고급 에러 처리 */
try{
willExcept.byebye()
console.log('try 구문 실행')
}catch(exception){
console.log('catch 구문 실행')
}finally{
console.log('finally 구문 실행') // 예외의 발생 여부와 관계없이 무조건 실행 됌
}
}
=> 결과값
[Running] node "/workspaces/codespaces-blank/index.js"
catch 구문 실행
finally 구문 실행
[Done] exited with code=0 in 0.059 seconds
3) 강제 예외 발생
(1) throw
: 사용자 정의 예외를 발생(throw)할 수 있습니다.
상황에 따라 강제로 예외를 발생시켜야 하는 경우가 있음
예외가 발생하면 현재 함수의 실행이 중지되고 throw
이후의 명령문은 실행되지 않습니다.), 제어 흐름은 콜스택의 첫 번째 catch블록으로 전달됩니다. 호출자 함수 사이에 catch
블록이 없으면 프로그램이 종료
- 기본 문법
//단순한 예외
throw 문자열;
//조금 더 자세하게 예외를 발생
throw new Error(문자열);
- throw 활용
/* 빈값 예외 처리 */
{
function test(){
let x = "";
try{
//개발자 직접 에러를 발생
if(x=="") throw "개발자 직접 에러 처리:빈값 입니다"
let y = x+20
console.log(y)
}catch(err){
console.log(`${err}`)
}finally{
//무조건 실행
console.log("finally구문은 try/catch문 제일 마지막에 무조건 실행")
}
}
//함수 호출
test()
}
=> 결과값
[Running] node "/workspaces/codespaces-blank/index.js"
개발자 직접 에러 처리:빈값 입니다
finally구문은 try/catch문 제일 마지막에 무조건 실행
[Done] exited with code=0 in 0.052 seconds
------------------------------------------------------------------
/* 0으로 나눌때 예외 처리 */
{
function divide(a,b){
if(b===0){
throw '0으로 나눌 수 없습니다.'
}
return a/ b
}
console.log(divide(10,0))
}
=> 결과값
[Running] node "/workspaces/codespaces-blank/index.js"
node:internal/process/esm_loader:100
internalBinding('errors').triggerUncaughtException(
^
0으로 나눌 수 없습니다.
(Use `node --trace-uncaught ...` to show where the exception was thrown)
Node.js v19.7.0
[Done] exited with code=1 in 0.048 seconds
- throw new Error 활용
/* object undefined 자세한 예외 처리 */
{
/* undefined+undefined는 NaN으로 나옴 */
function test(object){
// object.a와 object.b는 undefined
if(object.a !== undefined && object.b !== undefined){
console.log(object.a+object.b)
}else{
throw new Error('a 속성과 b 속성을 지정하지 않음')
}
}
test({})
}
=> 결과값
[Running] node "/workspaces/codespaces-blank/index.js"
file:///workspaces/codespaces-blank/index.js:8
throw new Error('a 속성과 b 속성을 지정하지 않음')
^
Error: a 속성과 b 속성을 지정하지 않음
at test (file:///workspaces/codespaces-blank/index.js:8:19)
at file:///workspaces/codespaces-blank/index.js:11:5
at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
Node.js v19.7.0
[Done] exited with code=1 in 0.049 seconds