Programming/Javascript

[Javascript] 예외 처리 try~catch~finally

Bam_t 2021. 5. 20. 16:11
728x90

이 구문은 ES2015이후의 내용은 아닙니다만 왜 지금 튀어나오냐면, 그 동안 작성했던 포스트들을 읽어내는 과정에서 예외 처리에 대한 부분이 빠져서 뒤늦게나마 보충하게 되었습니다.


0. 예외 처리가 사용되는 이유

모든 사용자가 프로그래머가 의도한 대로 프로그램을 사용할 수는 없습니다. 이런 상황들을 예외라고 부르는데, 코드 작성 과정에서 이런 예외를 막을 수 있는 것도 있지만, 외부 요인에 의해서 발생하는 예외들은 코드 작성 과정에서 이를 방지하기가 어렵습니다. 그래서 등장한 것이 예외 처리 구문입니다.

자바스크립트 코드는 코드를 읽어오다가 스크립트 상에서 예외가 발생하면 스크립트가 정지해버리는 상황이 생기게 됩니다. 이때 예외 구문을 이용한다면, 스크립트가 정지하는 상황은 피하면서 예외에 대한 상황에 대처할 수 있게 합니다.

 

 

 

1. try ~ catch ~ finally

예외 구문은 기본적으로 다음과 같은 형태로 사용됩니다.

try {
	예외가 발생할 수 있는 명령(들)
}
catch (에러 객체) {
	예외가 발생할 때의 처리(들)
}
finally {
	예외가 발생하거나, 발생하지 않아도 최종적으로 실행될 명령(들)
}

 

이 구문에서 finally블록이 필요하지 않다면 생략이 가능하고, try~catch 부분만 존재해도 상관 없습니다.

 

catch블록에서 인수로 에러 객체 라는 것이 넘어가는데, 이는 에러의 종류를 나타내며 에러 객체를 담는 변수로 e를 많이 이용합니다.

try구문에서 예외가 발생한다면 catch문을 실행하게 되지만 예외가 발생하지 않는다면 catch문의 실행없이 다음 스크립트가 실행됩니다.

 

간단한 예외 처리 예를 보겠습니다.

우선 예외 구문없는 일반적인 코드입니다.

let sum = 0;
let num1 = 2;

sum = num1 + num2;

console.log(sum);

이 코드만 봤을때 num2라는 것이 정의되어있지 않기때문에 오류가 나겠죠? 결과를 한 번 보겠습니다.

역시 예상대로 오류가 발생했습니다.

그렇다면 예외 구문을 이용한 구문을 살펴보겠습니다.

let sum = 0;
let num1 = 2;

try {
    sum = num1 + num2;	//오류가 발생할 가능성이 있음!
}
catch (e) {
    console.log(e.message);	//오류가 발생할 경우 message출력!
}
finally {
    console.log('sum: ' + sum + '\n')
    console.log('어쨋든 수행 완료!');
}

비록 코드는 길어졌지만 스크립트가 끝까지 실행되었음을 알 수 있습니다. 코드가 길어진 것 또한 위의 예시가 간단해서 길어진 것 뿐이지, 더 복잡한 과정에서의 예외 처리라면 더 간단하고 짧은 코드를 만들 수 있습니다.

 

콘솔창 첫 줄의 num2 is not defined라는 문구가 console.log(e.message)라는 구문에 의해 출력되었습니다.

message라는 것은 에러 객체의 프로퍼티로 에러에 대한 메세지를 가지고있는 프로퍼티입니다.

 

한가지 주의점은 예외 처리는 확실한 예외 처리를 보장하지만 처리에 시간과 메모리가 많이 소요됩니다. 그래서 남발하는 것과 반복문 내부에서 예외 처리를 기술하는 것은 피하는 것이 좋습니다.

 

 

 

 

2. throw

throw 명령은 명시적으로 예외를 발생시킬때 이용하는 명령입니다. throw 명령의 기본형태는 다음과 같습니다.

throw new Error(에러 메세지);

 

조금 전에본 예제를 조금 바꿔서 throw문의 예시를 보겠습니다.

let div = 0;
let num1 = 2;
let num2 = 0;

try {
    if (num2 === 0) {
        throw new Error('0으로 나누기');
    }
    div = num1 / num2;
}
catch (e) {
    console.log(e.message);
}

이 구문은 throw 명령을 이용해서 명시적으로 에러를 보내지 않았다면 2 나누기 0이라는 식에 에러가 없으므로 catch문을 실행하지 않게 됩니다. 그러나 정수를 0으로 나누는 경우를 예외 상황이라고 명시적으로 선언했기 때문에 catch문이 실행되었습니다.


728x90