JavaScript에서 발생하는 오류(Error)의 종류
일반적으로 프로그래밍 중 발생할 수 있는 오류는 3가지가 있습니다.
1. 구문 오류(Syntax Error)
JavaScript가 요구하는 규칙대로 프로그램을 작성하지 않을 경우 발생합니다. 예를 들면 다음과 같은 코드입니다.
▼ 구문 오류 발생 예제
console.log("안녕하세요"
consoe.log
호출 시 )
를 누락하였습니다. 따라서 코드를 실행해보면 SyntaxError: missing ) after argument list
라는 오류 문구를 출력합니다.
2. 실행시간 오류(Runtime Error, Exception)
이런 종류의 오류는 프로그램을 실행할 때 발생합니다. 다시 말해 실행(평가)해보기 전까지는 그곳에 오류가 있는지 알 수 없다는 뜻입니다.
다음의 실행시간 오류를 포함한 코드를 보겠습니다.
▼ 실행시간 오류 발생 예제
function sum(a, b) {};
add(2, 2);
이 코드는 실행하면 ReferenceError: add is not defined
라는 오류 문구를 출력합니다.
정의하지 않은 add
함수를 호출하는 오류가 포함되어 있습니다. 실제 코드에 함수 add
는 없고 sum
만 정의되어 있는 것이 눈에 보이지만 인터프리터(Interpreter)는 실행 명령을 받기 전까지는 작성자의 의도를 알 수 없습니다. 현재 이 코드가 아직 작성 중인 것일 수도 있으며, 혹은 다른 scope에 정의가 되어 있을 수도 있기 때문입니다. 구문 오류와 달리 JavaScript의 문법에는 오류가 없습니다.
3. 논리적인 오류
앞서 살펴본 2종류의 오류는 사실 인터프리터에 의해 자동으로 검출이 되므로 수정이 용이합니다. 때문에 2가지 종류의 오류는 사실 신경 쓸 부분이 많지 않습니다. 단지 콘솔에 출력되는 오류 문구를 구글에 검색해본 후 처리해주면 됩니다.
반면 논리적인 오류는 여러분의 프로그래밍에 논리적인 실수가 있을 때 발생합니다. 대부분의 경우 프로그램은 이러한 종류의 오류가 외부로 드러나지 않고 정상적으로 동작하기 때문에 프로그램 내부에 오류의 여부를 확인하기 힘듭니다.
따라서 대부분의 소프트웨어 시험(Software Testing)은 바로 이런 종류의 오류를 검출하고 수정하기 위해서 수행합니다.
예를 들어 다음과 같습니다.
▼ 논리적인 오류 예시
function add(a, b) {console.log(a*b)};
add(2, 2);
위 소스코드를 실행해보면 프로그램이 정상 실행되어 결과도 4
로 올바르게 화면에 출력합니다. 하지만 사실은 프로그래머가 계산 시 +
가 아닌 *
연산자를 사용한 잘못 구현한 함수입니다. (함수의 이름이 잘못되었을 수도 있습니다.)
논리적인 오류는 프로그램이 오류를 발생시키지 않기 때문에 증상을 외부로 드러내야 합니다.
논리적인 오류를 검출하기 위해 JavaScript와 같은 프로그래밍 언어들은 오류(예외)를 강제로 발생시킬 수 있습니다. 증상이 보지 않으면 내부의 오류를 알 수 없기 때문입니다.
Throw
예외를 발생시키기 위해 JavaScript에서는 throw
문을 사용합니다. 용법은 다음과 같습니다.
throw 표현식;
표현식에는 어떠한 값도 들어갈 수 있습니다. 때문에 다음과 같이 사용할 수도 있습니다.
throw "에러@Add"; // 문자열
throw 42; // 숫자
하지만 일반적으로 Error
객체를 사용합니다.
throw new Error(customError);
▼ 에러 객체 예외 발생 예제
function add(a,b) { return a*b; }
function addTest() {
let ret = add(2,3);
let exp = 5;
if (ret != exp) {
throw new Error('Error @ addFunction');
}
}
addTest();
▼ 에러객체 예외 발생 예제 실행결과
Uncaught Error: Error @ addFunction
Try, Catch, Finally
우리가 throw
를 사용해 의도적으로 발생시킨 오류를 포함해 앞서 오류의 예로 들었던 코드에서 발생시키는 예외들의 문구를 보면 다음과 같이 Uncaught
라는 문구가 붙어 있습니다. 그리고 공통적으로 프로그램의 구동이 그곳에서 중단되었습니다.
▼ 구문 오류 발생 예제 실행결과
Uncaught SyntaxError: missing ) after argument list
이것은 발생한 예외(오류)를 받아(catch) 처리할 수 있는 핸들러가 존재하지 않기 때문에 기본적으로 존재하는 예외처리 핸들러가 화면에 문구를 출력 후 프로그램을 종료시켰기 때문입니다. 반면에 이를 적절히 처리할 수 있는 핸들러가 있다면 프로그램은 오류가 아닌 정상 종료 또는 계속 실행될 것입니다.
JavaScript에서 제공하는 예외(오류)를 처리하는 방법은 Try, Catch 그리고 Finally 를 사용하는 것입니다.
우선 try 절 내부에 에러를 발생시킬 가능성이 있는 코드를 내부에 삽입합니다. 그 뒤로 오류를 처리할 수 있는 1개 이상의 catch 절이 뒤따르고 옵션으로 finally 절이 나올 수도 있습니다. 다음과 같이 3가지 형태를 띠게 됩니다.
- try-catch
- try-finally
- try-catch-finally
다음과 같이 사용할 수 있습니다.
▼ try - catch 예제
function add(a,b) { return a*b; };
function addTest() {
let ret = add(2,3);
let exp = 5;
if (ret != exp) {
throw new Error('Error @ addFunction');
}
};
try {
addTest();
} catch (e) {
console.log(e.name);
console.log(e.message);
};
앞서 기술했던 것과 같이 try 절 내부에 실행할 코드를 넣고, 해당 코드의 실행 결과 오류가 발생하였을 때 이를 받아 처리할 수 있는 코드를 catch 절 내부에 넣습니다. 예제에서는 발생한 error를 화면에 출력하였습니다.
▼ try - catch 예제 실행결과
Error
Error @ addFunction
사실, 실행 결과를 보면 화면에 출력되는 문구도 동일하며 앞선 결과와 크게 다르지 않습니다. 다른 점은 프로그램이 정상 종료되었다는 것입니다. 즉, 앞서 발생한 오류는 _catch_를 통해서 마무리(개발자에게 상황을 알려주고)가 되었고 나머지 코드는 정상 실행되는 것입니다. 때문에 만약 JavaScript 에 추가 더 실행할 코드가 있었다면 그대로 실행이 되었을 것입니다.
마지막으로 finally 절의 경우는 오류의 처리 여부와 관계없이 반드시 실행되는 코드를 넣습니다. 때문에 설령 미처리된 오류로 인하여 프로그램이 종료되는 경우도 finally 내부의 코드를 실행한 후 종료가 됩니다.
결론
우리들은 코드를 작성할 때 예외(오류)가 발생할 것을 기대하지는 않습니다. 때문에 try 구문에서 실행되는 코드가 예외를 발생시키지 않는 것이 제일 좋은 상황이겠지만 그것이 불가능한 경우도 있습니다. 때문에 try … catch 구문을 통하여 개발자에게 알려주어 이를 해결하거나, 예상되거나 해결이 가능한 오류인 경우, 자체적으로 적절히 처리하여 프로그램의 실행에 지장이 없도록 하는 것이 차선책이 될 것입니다.
'프로그래밍 언어 > Javascript' 카테고리의 다른 글
JavaScript의 모듈로 연산(Modulo Operation) (0) | 2020.02.13 |
---|---|
JavaScript - 타이머 (0) | 2018.07.07 |
객체, 배열, 함수 (0) | 2018.06.01 |
변수 (0) | 2018.05.31 |
프로그래밍 언어 (0) | 2018.05.26 |