
원문 - On JavaScript Errors
2025년 5월, Hayden Bleasel의 트윗 하나가 JavaScript 커뮤니티에 뜨거운 논쟁을 일으켰다. 그 내용은 단순했다:
“나는 모든 JS 프로젝트에 이 두 파일을 무조건 넣는다. 더 나은 방법이 있을까?”
![]() |
|---|
![]() |
이 단순한 질문은 많은 개발자들이 느껴온 JS 에러 처리의 불편함과 모순을 다시금 떠올리게 만들었다. 이 글은 그 논의의 핵심과 해결책, 그리고 다양한 접근 방식들을 정리한 것이다.
에러 처리는 단순히 예외를 잡는 것이 아니다. 앱이 예기치 않게 깨지는 걸 방지하고:
을 포함한다. JS에서는 try...catch, throw, Error 객체를 기본 도구로 제공한다.
try {
const data = await fetchData();
renderData(data);
} catch (err) {
console.error("에러 발생:", err);
showErrorToUser("데이터를 불러오지 못했습니다.");
}
JS의 에러는 호출 스택을 따라 위로 "버블링"된다. 처리되지 않으면 전역에 도달해 앱이 죽거나 콘솔 에러를 발생시킨다.
function C() {
throw new Error("에러!");
}
function B() { C(); }
function A() { B(); }
A(); // 최상단에서 에러 발생
이 구조는 에러를 고수준에서 처리할 수 있는 유연성을 제공하지만, 중간에 놓치면 치명적이다.
throw "문자열", throw { custom: true }, throw undefined 다 허용됨.error 필드를 넣음export const parseError = (error: unknown) => {
if (typeof error === 'string') return error;
if (error instanceof Error) return error.message;
return '알 수 없는 에러 발생';
};
// parseError.ts
export const parseError = (error: unknown) => {
if (typeof error === 'string') return error;
if (error instanceof Error) return error.message;
return 'An error occurred';
};
// handleError.ts
import { toast } from 'sonner';
import { parseError } from './parseError';
export const handleError = (title: string, error: unknown) => {
const description = parseError(error);
toast.error(title, { description });
};
위 코드 조합은 단순하지만 강력하다:
장점: 간단, 의존성 없음, 모두가 이해함
단점: 실수에 취약함 (ex. try 누락, 로그 누락 등)
neverthrow: Rust 스타일 Result<T, E>const result = getUserById(id);
if (result.isErr()) handle(result.error);
else render(result.value);
장점:
map, mapErr, match 등)단점:
Effect: 완전한 함수형 에러 시스템Effect는 Effect<E, A>라는 타입으로 오류 가능성을 타입에 반영함. 이는 Haskell이나 Scala의 영향을 받은 타입 기반 오류 추적 시스템이다.
장점:
단점:
JavaScript는 본질적으로 유연성 중심 언어:
결국 에러 처리는 자율성 + 규율의 균형 문제다. 다양한 해결책이 존재하는 이유도 그 때문이다.
.catch 또는 try/catch 작성handleError 호출"parseError, handleError)neverthrow, Effect 고려에러 처리 방식은 정답이 없다. 프로젝트 규모, 팀 문화, 코드 스타일에 따라 적절한 선택지가 다를 수 있다. 다만 가장 나쁜 것은 아무 것도 하지 않는 것이다.
에러는 언제든지 발생한다. 중요한 건 그걸 어떻게 다룰지에 대한 전략이 있는가다.
throw new Error('읽어주셔서 감사합니다!');