throw

throw

throw 문은 사용자 정의 예외를 던집니다. 현재 함수의 실행이 중단되고(throw 뒤의 문들은 실행되지 않습니다), 제어는 호출 스택(call stack)의 첫 번째 catch 블록으로 전달됩니다. 호출 함수들 사이에 catch 블록이 없으면 프로그램이 종료됩니다.

출처: throw

본문

throw 문은 사용자 정의 예외를 던집니다. 현재 함수의 실행이 중단되고(throw 뒤의 문들은 실행되지 않습니다), 제어는 호출 스택의 첫 번째 catch 블록으로 전달됩니다. 호출 함수들 사이에 catch 블록이 없으면 프로그램이 종료됩니다.

구문 (Syntax)

throw expression;
  • expression: 던질 표현식입니다.

설명 (Description)

throw 문은 문을 사용할 수 있는 모든 컨텍스트에서 유효합니다. 실행되면 호출 스택을 관통하는 예외를 생성합니다. 오류 버블링과 처리에 대한 자세한 내용은 제어 흐름과 오류 처리(Control flow and error handling)를 참조하세요.

throw 키워드 뒤에는 어떤 종류의 표현식이라도 올 수 있습니다. 예를 들어:

throw error; // Throws a previously defined value (e.g. within a catch block)
throw new Error("Required"); // Throws a new Error object

실제로 던지는 예외는 항상 Error 객체이거나 RangeError 같은 Error 하위 클래스의 인스턴스여야 합니다. 오류를 잡는 코드가 잡힌 값에 message 같은 특정 속성이 있다고 기대할 수 있기 때문입니다. 예를 들어 웹 API는 일반적으로 Error.prototype에서 상속받는 DOMException 인스턴스를 던집니다.

자동 세미콜론 삽입 (Automatic semicolon insertion)

구문은 throw 키워드와 던질 표현식 사이에 줄 종결자(line terminator)를 금지합니다.

throw
new Error();

위 코드는 자동 세미콜론 삽입(ASI)에 의해 다음으로 변환됩니다.

throw;
new Error();

이것은 유효하지 않은 코드인데, return과 달리 throw 뒤에는 반드시 표현식이 와야 하기 때문입니다. 이 문제를 피하려면 괄호를 사용할 수 있습니다.

throw (
  new Error()
);

예제: 사용자 정의 오류 던지기

입력이 기대한 타입이 아니면 TypeError를 던지는 함수를 정의하는 예제입니다.

function isNumeric(x) {
  return ["number", "bigint"].includes(typeof x);
}

function sum(...values) {
  if (!values.every(isNumeric)) {
    throw new TypeError("Can only add numbers");
  }
  return values.reduce((a, b) => a + b);
}

console.log(sum(1, 2, 3)); // 6
try {
  sum("1", "2");
} catch (e) {
  console.error(e); // TypeError: Can only add numbers
}

예제: 기존 객체 던지기

콜백 기반 async 함수를 호출하고, 콜백이 오류를 받으면 오류를 던지는 예제입니다.

readFile("foo.txt", (err, data) => {
  if (err) {
    throw err;
  }
  console.log(data);
});

이렇게 던진 오류는 호출자에 의해 잡힐 수 없으며 (a) readFile 함수 자체가 오류를 잡거나, (b) 프로그램이 최상위 오류를 잡는 컨텍스트에서 실행되지 않는 한 프로그램이 중단됩니다. Promise() 생성자를 사용하면 더 자연스럽게 오류를 처리할 수 있습니다.

function readFilePromise(path) {
  return new Promise((resolve, reject) => {
    readFile(path, (err, data) => {
      if (err) {
        reject(err);
      }
      resolve(data);
    });
  });
}

try {
  const data = await readFilePromise("foo.txt");
  console.log(data);
} catch (err) {
  console.error(err);
}

더 알아보기