JavaScript에서 에러를 발생시킬 때 throw new Error()와 throw someObject는 비슷해 보이지만, 실제로 동작 방식에 중요한 차이가 있습니다. 이 두 가지 방식의 차이를 정확히 이해하면 더 일관성 있고 디버깅하기 쉬운 코드를 작성할 수 있습니다.
throw new Error()의 동작 방식
throw new Error()는 생성자에 전달된 값을 Error 객체로 감싸서(wrap) 던집니다. 이때 생성되는 객체는 다음과 같은 구조를 가집니다.
{
name: 'Error',
message: '생성자에 전달한 메시지'
}즉, 문자열을 전달하더라도 자동으로 표준 Error 객체 형태로 변환되기 때문에 name과 message 속성을 통해 일관된 방식으로 에러 정보에 접근할 수 있습니다.
throw someObject의 동작 방식
반면 throw someObject는 전달된 객체를 그대로 있는 그대로(as-is) 던집니다. 어떠한 변환도 일어나지 않으며, 숫자, 문자열, 일반 객체 등 어떤 값이든 던질 수 있습니다.
throw { errorCode: 404, reason: 'Not Found' };
throw '단순 문자열도 가능';
throw 42;공통점: try 블록 실행 중단
두 방식 모두 try 블록 내에서 호출되면 즉시 코드 실행을 중단하고, 가장 가까운 catch 블록으로 제어를 넘깁니다. 이 점에서는 차이가 없습니다.
그렇다면 무엇을 사용해야 할까?
일반적으로는 throw new Error() 사용이 권장됩니다. 그 이유는 다음과 같습니다.
- 스택 추적(Stack Trace) 제공: Error 객체는 에러가 발생한 위치를 보여주는 스택 정보를 포함합니다.
- 일관된 구조:
catch(err)에서 항상err.message,err.name으로 접근할 수 있어 코드 예측성이 높아집니다. - 디버깅 용이성: 개발자 도구와 로깅 시스템이 Error 객체를 더 잘 인식합니다.
다만 커스텀 에러 정보를 함께 전달해야 하는 경우에는 Error를 상속한 커스텀 에러 클래스를 만들거나, Error 객체에 속성을 추가하는 방식이 좋습니다.
class HttpError extends Error {
constructor(statusCode, message) {
super(message);
this.name = 'HttpError';
this.statusCode = statusCode;
}
}
throw new HttpError(404, '리소스를 찾을 수 없습니다');정리
throw new Error()는 값을 표준 Error 객체 형식({ name, message })으로 감싸서 던지고, throw someObject는 객체를 그대로 던진다는 것이 핵심 차이입니다. 둘 다 try 블록의 실행을 중단시키지만, 스택 추적과 일관성 측면에서 new Error() 또는 이를 상속한 커스텀 에러 클래스를 사용하는 것이 베스트 프랙티스입니다.