React 16의 Error Boundary로 예외 처리 개선하기
문제 상황
프로덕션 환경에서 특정 컴포넌트의 렌더링 에러로 인해 전체 앱 화면이 백화면으로 변하는 이슈가 발생했다. 사용자는 새로고침 외에는 복구 방법이 없었고, Sentry에 쌓인 에러 로그만으로는 정확한 원인 파악이 어려웠다.
Error Boundary 도입
React 16에서 추가된 componentDidCatch 라이프사이클을 활용해 Error Boundary를 구현했다.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null };
}
componentDidCatch(error, errorInfo) {
this.setState({ hasError: true, error });
// Sentry 등 에러 트래킹 서비스로 전송
logErrorToService(error, errorInfo);
}
render() {
if (this.state.hasError) {
return (
<div className="error-fallback">
<h2>일시적인 오류가 발생했습니다</h2>
<button onClick={() => window.location.reload()}>
새로고침
</button>
</div>
);
}
return this.props.children;
}
}
적용 전략
전체 앱을 하나의 Error Boundary로 감싸지 않고, 주요 영역별로 분리해 적용했다. 대시보드, 사이드바, 메인 콘텐츠 영역을 각각 감싸서 한 영역의 에러가 다른 영역에 영향을 주지 않도록 했다.
<Layout>
<ErrorBoundary>
<Sidebar />
</ErrorBoundary>
<ErrorBoundary>
<MainContent />
</ErrorBoundary>
</Layout>
결과
부분적인 에러 발생 시에도 앱의 나머지 부분은 정상 작동하게 되었다. 에러 정보도 더 구조화되어 수집되어 디버깅이 수월해졌다. 다만 이벤트 핸들러 내부의 에러는 여전히 try-catch로 처리해야 한다는 점을 주의해야 한다.