47.1 에러 처리의 필요성

에러가 발생하지 않는 코드를 작성하는 것은 불가능하며, 직접적으로 에러를 발생하지는 않는 예외적인 상황도 있기 때문에 발생한 에러나 예외적인 상황에 적절하게 대응할 필요성이 있다.

만약 에러나 예외적인 상황에 대응하지 않으면 프로그램은 강제 종료되며, 문제점의 원인을 파악하기 어렵기 때문에 대응하기 어려워 빠른 대처가 힘들어진다.

47.2 try … catch … finally 문

기본적으로 에러 처리(error handling)를 구현하는 방법에는 크게 두 가지가 있다.

  1. if 문이나 단축 평가 또는 옵셔널 체이닝 연산자를 통해 확인해서 처리하는 방법
  2. 에러 처리 코드를 미리 등록해 두고 에러가 발생하면 에러 처리 코드로 점프하도록 하는 방법

try … catch … fiinally 문은 두 번째 방법을 사용하며, 일반적으로 이 방법을 에러 처리라고 한다.

finally 문은 불필요하다면 생략이 가능하며, catch 문도 생략 가능하지만 무의미하기 때문에 생략하지 않는다.

try {
	(에러가 발생할 가능성이 있는 코드)
} catch (err) {
	(try 코드 블록에서 에러가 발생하면 이 코드 블록의 코드가 실행된다.)
	(err에는 try 코드 블록에서 발생한 Error 객체가 전달된다.)
} finally {
	(에러 발생과 상관없이 반드시 한 번 실행된다.)	
}

47.3 Error 객체

Error 생성자 함수는 에러 객체를 생성하며, 에러를 상세히 설명하는 에러 메시지를 인수로 전달할 수 있다.

const error = new Error('Error Message');

Error 생성자 함수가 생성한 에러 객체는 message 프로퍼티와 stack 프로퍼티를 갖는다.

message 프로퍼티의 값은 Error 생성자 함수에 인수로 전달한 에러 메시지이고,

stack 프로퍼티의 값은 에러를 발생시킨 콜 스택의 호출 정보를 나타내는 문자열이며 디버깅 목적을 가진다.

자바스크립트는 Error 생성자 함수를 포함해 7가지의 에러 객체를 생성할 수 있는 Error 생성자 함수를 제공 중에 있으며, 각 Error 생성자 함수가 생성한 에러 객체의 프로토타입은 모두 Error.prototype을 상속받는다.

생성자 함수 인스턴스
Error 일반적 에러 객체
SyntaxError 자바스크립트 문법에 맞지 않는 문을 해석할 때 발생하는 에러 객체
ReferenceError 참조할 수 없는 식별자를 참조했을 때 발생하는 에러 객체
TypeError 피연산자 또는 인수의 데이터 타입이 유효하지 않을 때 발생하는 에러 객체
RangeError 숫자값의 허용 범위를 벗어났을 때 발생하는 에러 객체
URIError encodeURI 또는 decodeURI 함수에 부적절한 인수를 전달했을 때 발생하는 에러 객체
EvalError eval 함수에서 발생하는 에러 객체

47.4 throw 문

Error 생성자 함수로 에러 객체를 생성한다고 에러가 발생하는 것은 아니다.

즉, 에러 객체 생성과 에러 발생은 의미가 다르다.

에러를 발생시키려면 try 코드 블록에서 throw 문으로 에러 객체를 던져야 한다.

throw expression;

throw 문의 표현식(expression)은 어떤 값이라도 상관없지만 일반적으로 에러 객체를 지정한다.

에러를 던지면 catch 문의 에러 변수가 생성되고 던져진 에러 객체가 할당된 후, catch 코드 블록이 실행된다.

47.5 에러의 전파

에러는 **호출자(caller) 방향 : 콜 스택의 아래 방향(실행 중인 실행 컨텍스트가 푸시되기 전에 푸시된 실행 컨텍스트 방향)**으로 전파된다. 하지만 앞에서 살펴본 바와 같이 setTimeout 함수의 콜백 함수를 호출한 것은 setTimeout 함수가 아니기 때문에 콜백 함수가 발생시킨 에러는 catch 블록에서 캐치되지 않아 프로세스는 종료된다. - 1.2절 에러 처리의 한계 에서 알 수 있듯이, 에러는 호출자 방향으로 전파된다.

단, setTimeout 함수나 프로미스 후속 처리 메서드의 콜백 함수는 호출자가 없다는 것에 주의해야 한다.