에러바운더리가 비동기요청 이나 이벤트 핸들러에서 발생한 오류는 잡지 못한다는 걸 알고 있었다.
하지만, 런타임 에러(TypeError)에서 발생한 오류를 잡지 못하고 있었다.
구글링을 한참을 해도 원인을 못찾겠어서 오류를 다시보는데..

아래에 Hey developer 부분을 자세히보니 ErrorBoundary나 errorElement를 라우트 props에 전달하라고 나와있었다.
평소에 오류가 뜨면 맨 윗줄만 읽는 습관을 가지곤 했는데 앞으론 꼼꼼히 살펴봐야겠다.
createBrowserRouter를 사용하면, Navigator 컴포넌트에서 일어난 에러는 상위(에러바운더리)로 올라가지 않고 내부에서 처리하고 있는 것이다. 다만, 라우팅에서 이러한 설정을 하지 않아서 그대로 에러가 나는 것이다.
react-router-dom v6.9.0 버전(2023-03-10) 에서는 라우트 설정의 props인 errorElement 또는 ErrorBoundary 를 통해 에러가 일어나면 fallback페이지를 보여주는 기능을 제공하고 있었다.
(참고로 두 props의 로직은 똑같고, 동시에 사용할 경우 ErrorBoundary가 적용된다고 한다.)
사용방법은 다음과 같이 아주 간단하다. 그냥 원하는 fallbackComponent를 명시하면 된다.
const router = createBrowserRouter([
{
element: <MainLayout />,
errorElement: <NotFound />,
}
// ... 생략
]
)
그렇다면 errorElement와 React 16버전부터 제공되는 ErrorBoundary를 어떻게 구분해서 사용해야할까?

스택오버플로우 답변에 따르면..
errorElement 는 로더, 액션, 컴포넌트 렌더링에서 예외가 발생하면 오류 경로로 렌더링해 fallback 컴포넌트를 보여주고 useRouteError 를 통해 에러를 제공한다고 한다.
로더, 액션, 컴포넌트 렌더링을 처리할때 발생하는 특정 경우는 errorElement 로 처리하는것이 유용하고, 그 외의 일반적인 예기치 않은 오류는 에러바운더리로 처리하는 것이 유용하다고 한다. 에러바운더리는 에러 경계의 범위를 좁혀 특정 UI만 fallback UI로 보여줄 수 있는 것이 장점인데, errorElement는 에러처리를 useRouteError와 더불어 좀 더 선언적으로 할 수 있다고 한다.
따라서, 원래 ErrorBoundary 를 통해 에러분기처리를 하고 싶었는데 이는 위에서 언급한 useRouteError로 해결이 가능하다.
const NotFound = () => {
const error = useRouteError()
console.log(error)
if(error instanceof AxiosError){
// ...
}
if(error instanceof ValidationError){
// ...
}
if(error instanceof SyntaxError){
// ...
}
}

에러를 받아온 모습이고, 에러바운더리와 같이 커스텀 에러타입을 받아서 그에 맞게 에러처리를 할 수 있다.
정리하자면,
라우트에서 설정한 로더, 액션, 컴포넌트 렌더링에 대한 오류는 errorElement를 이용하고, 그 외에 예상치못한 오류는 에러바운더리로 처리하는 것이 좋은 방향이 아닐까 싶다.

런타임에러 발생시 지정한 404페이지가 잘 렌더링된다.
근데 사실, errorElement도 에러바운더리와 같이 특정 UI만 좁게 fallback으로 보여줄 수 있는데 사용하면 안되는 것일까? 비동기, 이벤트 핸들러의 오류를 잡기 위해 tanstack-query 의 옵션 + ErrorBoundary 를 조합해서 사용하곤 하는데 errorElement로는 불가능한건가?
react-router-dom의 errorElement로 에러 핸들링하기
Error boundaries vs errorElement from react-router-dom package
CHANGELOG.md