[JavaScript] 예외처리(Exception Handling)


1. Error

런타임 오류가 발생했을 때 던져짐

1) 프로그래밍의 에러 3가지

(1). 문법 에러 : 문법상 맞지 않아서 발생하는 에러 (컴파일 시 에러가 있다고 알려줌)

(2). 런타임 에러 : 문법은 어긋나지 않지만 실행시에 오류가 발생. (존재하지 않는 메소드를 호출)

(3). 논리적 에러 : 문법적으로도 맞고 실행시에 아무런 문제가 발생하지 않지만 원하는 값이 안나오는 에러(로직이 잘못되어서 발생하는 에러)


2) Error types

(1) SyntaxError: 문법적으로 유효하지 않은 코드를 해석하려고 시도할 때 발생하는 오류를 의미

[SyntaxError - JavaScriptMDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError)

에러발생이유

  • 문법적으로 유효하지 않은 코드 사용

(2) ReferenceError : 현재 범위에서 존재하지 않거나 초기화되지 않은 변수를 참조했을 때 발생

[ReferenceError - JavaScriptMDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError)

에러발생이유


(3) RangeError : 어떤 값이 집합에 없거나 허용되는 범위가 아닐 때 오류

[RangeError - JavaScriptMDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/RangeError)

에러발생이유


(4) TypeError : 일반적으로 값이 기대하던 자료형이 아니라서 연산을 할 수 없을 때 발생하는 오류

[TypeError - JavaScriptMDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/TypeError)

에러발생이유

  • 함수에 전달된 피연산자 또는 인수가 해당 연산자나 함수가 예상하는 타입과 호환되지 않을 경우
  • 변경할 수 없는 값을 수정하려고 할 경우
  • 부적절한 방법으로 값을 사용하려고 할 경우

(5) URIError: URIError객체는 전역 URI 핸들링 함수가 잘못된 방식으로 사용되었을 때의 오류를 표현함.

[URIError - JavaScriptMDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/URIError)

에러발생이유

  • encodeURI()decodeURl() 함수에 부적절한 매개변수를 제공했을 때 발생하는 오류의 인스턴스를 생성합니다.

(6) EvalError: 전역 eval() 함수에 관한 오류

[EvalError - JavaScriptMDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/EvalError)

JavaScript에 의해 더 이상 발생하지 않지만 EvalError객체는 하위 호환성을 위해 남아있습니다.


(7) InternalError: JavaScript 엔진 내부에서 발생한 오류

비표준: 이 기능은 비표준이므로 실제 프로덕션에서 사용하지 마세요. 모든 사용자 환경에서 작동하지 않을 수 도 있으며, 미래에 호환성 문제가 생길 수 있습니다.

[EvalError - JavaScriptMDN](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값 유형에 대한 오류가 발생
URIErrorencodeURI( )
에서 오류가 발생 
EvalErroreval( )함수에서 오류가 발생
** 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