새로운 에러 리포팅

532025년 10월 07일4

React 19는 사용자 경험(UX)뿐만 아니라, 개발자 경험(DX)을 향상시키는 데에도 많은 노력을 기울였다. 그중에서도 개발자가 가장 빈번하게 마주치는 고통스러운 순간, 바로 ‘에러’를 다루는 방식에 대한 근본적인 개선 작업이 이루어졌다.

과거의 React는 에러가 발생했을 때, 브라우저 콘솔에 여러 줄의 암호 같은 메시지를 쏟아내는 것으로 유명했다.

Uncaught TypeError: Cannot read properties of undefined (reading 'map')
    at MyComponent (MyComponent.js:12)
    at renderWithHooks (react-dom.development.js:16305)
    at mountIndeterminateComponent (react-dom.development.js:20074)
    at beginWork (react-dom.development.js:21587)
    ... (수십 줄의 내부 호출 스택)

이 메시지는 에러가 발생했다는 사실과 그 위치(MyComponent.js의 12번째 줄)를 알려주었지만, ‘왜’ 발생했는지에 대한 정보는 턱없이 부족했다. 특히 경험이 적은 개발자에게 이 호출 스택(call stack)은 해독 불가능한 외계어와도 같았다. undefined에서 .map을 호출했다는 사실을 파악하기까지 한참을 헤매야 했다.

“우리의 에러 메시지는 너무 불친절합니다.”

개발자 경험 개선 태스크 포스를 이끌던 한 엔지니어가 회의에서 말했다.

“에러는 개발 과정의 자연스러운 일부입니다. 우리는 에러를 처벌처럼 보여줄 것이 아니라, 개발자가 문제를 더 빨리 해결할 수 있도록 돕는 유용한 가이드로 만들어야 합니다.”

이 철학을 바탕으로, React 19의 에러 리포팅 시스템은 완전히 새롭게 설계되었다. 목표는 명확했다: 더 적은 정보가 아니라, ‘더 유용한’ 정보를, ‘더 읽기 쉬운’ 형태로 제공하는 것.

팀은 가장 흔하게 발생하는 에러 유형들을 분석하고, 각 상황에 맞는 맞춤형 에러 메시지를 만들기 시작했다.

가장 먼저, 무의미한 내부 호출 스택을 대폭 줄였다. 개발자는 React 내부에서 무슨 일이 일어나는지 알 필요가 없었다. 중요한 것은 개발자 자신이 작성한 코드의 어느 부분에서 문제가 시작되었는지였다.

그리고 에러 메시지 자체에 훨씬 더 많은 컨텍스트를 담았다.

Before:
Uncaught TypeError: Cannot read properties of undefined (reading 'map')

After (React 19):

Error: Rendered more hooks than during the previous render.
  
This is not allowed and is often caused by a Hook call being inside a-
condition (e.g. `if` or `&&`).

  12 |   if (props.showList) {
> 13 |     const [items, setItems] = useState([]); // <--- This Hook is called conditionally
  14 |   }

(※ 위 예시는 훅 규칙 위반 에러에 대한 개선된 포맷의 가상 예시입니다.)

새로운 에러 메시지는 충격적일 정도로 친절했다.

  • 에러의 원인을 일반적인 언어로 명확하게 설명해주었다. (Rendered more hooks...)
  • 에러가 발생하는 흔한 원인까지 짚어주었다. (...often caused by a Hook call being inside a condition...)
  • 문제가 발생한 코드 라인을 시각적으로 명확하게 표시해주었다.

이것은 단순한 텍스트의 변화가 아니었다. React가 개발자를 대하는 태도의 변화였다. React는 더 이상 ‘네가 틀렸어’라고 차갑게 말하는 대신, ‘이런 실수를 한 것 같은데, 혹시 이걸 확인해볼래?’라고 친절하게 말을 건네는 페어 프로그래밍 파트너처럼 다가갔다.

또한, 서버 컴포넌트에서 발생한 에러와 클라이언트 컴포넌트에서 발생한 에러를 명확히 구분하여, 에러가 발생한 ‘장소’를 쉽게 파악할 수 있도록 개선했다. 서버 에러는 터미널에, 클라이언트 에러는 브라우저 콘솔에 각각 최적화된 형태로 출력되었다.

이 새로운 에러 리포팅 시스템은 개발의 좌절감을 희망으로 바꾸는 작은 혁신이었다. 디버깅에 쏟는 시간이 줄어들고, 개발자들은 문제 해결 과정에서 더 많은 것을 배울 수 있게 되었다. React 19는 보이지 않는 곳에서부터 개발자의 경험을 세심하게 배려하며, 더욱 성숙하고 신뢰할 수 있는 도구로 거듭나고 있었다.