Frontend Development

React의 Error Boundary와 비동기 오류 처리

Kun Woo Kim 2025. 10. 13. 10:29
728x90

React의 Error Boundary는 컴포넌트 렌더링 도중 발생하는 오류를 포착하여 앱이 완전히 중단되지 않도록 돕는 강력한 기능입니다.
하지만 한 가지 중요한 한계가 있습니다 — 비동기 코드에서 발생한 오류는 Error Boundary가 잡을 수 없습니다.


##
왜 Error Boundary는 비동기 에러를 잡지 못할까?

그 이유는 비동기 에러가 렌더링 시점의 콜스택이 모두 비워진 후에 발생하기 때문입니다.

React는 컴포넌트를 렌더링할 때 하나의 연속된 콜스택 안에서 작업을 수행하며, Error Boundary 또한 이 흐름 안에서만 동작합니다.
즉, 동기적인 렌더링 과정 중에 발생한 오류만 감지할 수 있습니다.

class MyComponent extends React.Component {
  render() {
    throw new Error("렌더링 중 에러 발생!");
  }
}

위 코드는 렌더링 시점에 오류가 발생하므로 Error Boundary가 감지할 수 있습니다.

하지만 다음과 같은 코드는 다릅니다.

class MyComponent extends React.Component {
  componentDidMount() {
    setTimeout(() => {
      throw new Error("비동기 에러!");
    }, 1000);
  }
  render() {
    return <div>비동기 테스트</div>;
  }
}

이 경우, setTimeout 내부에서 발생한 오류는 렌더링이 완료된 후 콜스택이 비워진 뒤에 실행되므로,
Error Boundary는 이를 감지하지 못합니다.


비동기 오류를 처리하는 방법

비동기 오류는 직접적으로 처리해야 합니다. 대표적인 방법은 다음과 같습니다.

1. try...catch로 감싸기

async function fetchData() {
  try {
    const res = await fetch("/api/data");
    const data = await res.json();
  } catch (err) {
    console.error("비동기 에러 발생:", err);
  }
}

try...catch를 사용하면 비동기 코드 내에서 발생하는 예외를 직접 잡을 수 있습니다.


2. 상태(state)로 에러를 관리하기

비동기 에러를 감지하면 setState로 에러 상태를 저장하고, 이를 렌더링 시점에 반영할 수 있습니다.

function AsyncComponent() {
  const [error, setError] = useState(null);

  useEffect(() => {
    async function run() {
      try {
        const res = await fetch("/api/data");
        if (!res.ok) throw new Error("서버 응답 오류");
      } catch (err) {
        setError(err);
      }
    }
    run();
  }, []);

  if (error) {
    throw error; // 동기 에러로 재던짐 → Error Boundary가 감지
  }

  return <div>데이터 로딩 중...</div>;
}

이 방식은 비동기 에러를 Error Boundary로 전달하기 위해 의도적으로 동기 에러로 변환하는 기법입니다.


정리

구분 Error Boundary로 감지 가능 여부 예시
렌더링 중 에러 ✅ 가능 render() 내부에서 throw
생명주기 메서드 동기 에러 ✅ 가능 componentDidMount 내부의 throw
비동기 함수 내부 에러 ❌ 불가능 Promise, setTimeout, fetch
비동기 → 동기로 변환 ✅ 가능 setStatethrow error

결론

Error Boundary는 렌더링 시점에 발생하는 동기 오류만 잡을 수 있다.
비동기 에러는 직접 핸들링하거나, 상태를 통해 동기 에러로 전환해야 한다.

이 원리를 이해하면 React 애플리케이션의 안정성을 훨씬 높일 수 있습니다.

728x90