티스토리 뷰
ErrorBoundary를 왜 설정하려 하는가?
- ErrorBoundary에 대해 처리해서 Error상황이 발생하였을 때 사용자에게 어떤 원인으로 문제가 생겼는지 알려줘야 한다.
- 현재 Error에 대해서 잡아주는 코드가 없기 때문에 Error 코드 설정을 따로 해야한다.
생각하기
if (error) return <Error />
- if문으로 뺄 경우 error, loading, ui, data 없을 때 4가지로 분기가 되야한다. 어떻게 구현할까?
- error만 따로 관리해서공통컴포넌트처럼 관리해보자.
catch해야 할 error는 무엇이 있을까?
- AuthError (ApiErrorBoundary 에서 처리)
- network Error (ApiErrorBoundary 에서 처리)
- Unkown Error
AuthError
어떻게 구현해야 할까?
- 쿠키 체크, 서버에 요청
- 401에러 반환 시 AuthError를 통해 로그인으로 redirect 시킬 것
Network Error
어떻게 적용해야 할까?
- 500 반환 시 NetWorkError를 컴포넌트를 실행시킬 것
- 재시도 버튼을 통해 사용자가 재시도 할 수 있게 해주자.
실제 구현하기
- 어떻게 구현했는지?
- 어려웠던 점은?
- 앞으로 어떻게 개선할지?
어떻게 구현했는지?
문제
기존 코드의 경우 다음과 같은 문제점이 있었다.
- 분기에 따라 처리해야 되는 코드, 만약 등록된 일정이 하나도 없다면 생성 버튼이 나오는 컴포넌트가 나와야 하고 아닐 경우엔 목록을 보여주면 되는데 삼항 연산자로 처리를 해놔서 코드가 지저분한 느낌이 있었다.
즉, 분기가 많아서 관심사를 분리하고 싶다 - loading에 대한 문제, 비동기로 처리해야 되는 컴포넌트임에도 불구하고 로딩상태를 구현하지 않았다.
- 에러 처리가 전혀 되어있지 않다. 보통 다른 어플리케이션의 경우 다시시도나 toast 메시지로 사용자가 원하는 시나리오대로 동작하지 않을때에 대한 처리방법이 있는데 이런 부분들에 대한 적용이 미흡했다.
방안
- 가장먼저 componentDidCatch를 사용할 수 있게 errorboundary를 이용해 throw error 에 대한 처리가 필요하였다.
- children을 이용하여 error,fetch,container 3개의 컴포넌트로 나누어 각자의 관심사를 분리시켰다.
- 카카오 fe블로그가 많은참조가 되었다.
https://fe-developers.kakaoent.com/
홈 | 카카오엔터테인먼트 FE 기술블로그
fe-developers.kakaoent.com
어려웠던 점은?
Errorboundary가 생각한데로 동작하지 않았다. 에러가 발생하면 해당 생명주기를 통해 처리를 하는 방식이라고 배웠는데 internel server error가 발생하여 기존의 500.js 페이지를 띄워 재시도 버튼이나 문구가 전혀 나오지 않았다.
원인이 무엇일까?
- ssr이기 때문에 page를 생성하는 과정에서 thorw가 발생하면 componentDidCatch에서 처리를 해주지 못하고 500.js를 띄우게 된다.
- nextjs의 경우 에러가 발생하면 error modal을 무조건 띄워서 실제 error boundary를 처리하는 부분에서 어려움을 느낀다.
그러면 해결방법은 어떻게 될까?
- 현재 page router를 사용하는 방안 (
현재는 page router를 사용하고 있기 때문에 기각.)
https://nextjs.org/docs/app/building-your-application/routing/error-handling - 현재는 page router를 쓰고있기 때문에 tsx 파일에서 throw error를 시킨다.
Routing: Error Handling | Next.js
Using App Router Features available in /app
nextjs.org
// react-query를 사용하여 data안에 error state를 만들어 줌.
if (data?.pages[0].error) {
throw new Error(data?.pages[0].error.message, { cause: { type: data?.pages[0].error.type } });
}
한계
hooks나 api부분에서 throw error를 하게되면 ssr때문에 페이지를 생성하지 못해 원하는 UI를 보여주지 못하고 500.js로 넘어간다. 그렇기에 useQuery에서 제공하는 error state를 사용하지 못하고 data에 error를 담겨서 보내는 식으로 임시방편을 써야했다. 누군가 처음 코드를 보면 이상하게 짰다고 생각이 들 것이다. ㅠㅠ
최종코드
- UI 부분의 경우 관심사를 다음과 같이 분리했다.
- data안에 담겨있는 error를 보내주어서 error를 발생시키는 것이 현재 단계에서의 한계인데.. 더좋은 방법이 생각나면 개선 시켜야겠다.
export default function AchievementStatus() {
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } = useFetchAchievements();
return (
<ApiErrorBoundary error={data?.pages[0].error}>
<AchievementFetcher data={data} isLoading={isLoading}>
<AchievementContainer
data={data}
fetchNextPage={fetchNextPage}
hasNextPage={hasNextPage}
isFetchingNextPage={isFetchingNextPage}
/>
</AchievementFetcher>
</ApiErrorBoundary>
);
}
- error boundary는 react 문서를 참고하였을때랑 별로 다르지 않다.
https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary - auth error도 원래 추가시키려 하였으나 기존 컴포넌트가 번쩍하고 나왔다가 로그인창으로 변하는게 별로 좋지 않아서 다른 방안으로 접근해보려 한다.
Component – React
The library for web and native user interfaces
react.dev
export default class ApiErrorBoundary extends React.Component<
PropsWithChildren<ApiErrorBoundaryProps>,
AuthErrorBoundaryState
> {
constructor(props: ApiErrorBoundaryProps) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(): void {}
render() {
if (!this.state.hasError) {
return this.props.children;
}
if (this.props.error?.type === 'network') {
return <NetworkError />;
}
return <UnknownError />;
}
}
'사이드 프로젝트' 카테고리의 다른 글
Error handling 삽질하기 (2) | 2023.12.04 |
---|---|
[nextjs/eslint] next/babel parsing error 해결하기 (0) | 2023.07.17 |
[storybook] React is not defined 문제 해결하기 (0) | 2023.04.12 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- 선언적 UI
- serverless nestjs
- nestjs 배포하기
- 에러핸들링
- suspense 장점
- 서버사이드 error handling
- javascript
- nextjs 에러핸들링
- React useMemo
- serverless 배포
- 미로탈출 명령어
- storybook scss import
- 표현 가능한 이진트리
- 1600 파이썬
- 백준 22862
- 관심사 분리하기
- storybook react is not defiend 해결
- 불량 사용자 자바스크립트
- React useCallback
- 자바스크립트
- react suspense
- storybook scss이슈
- 백준 1600번
- 가장 긴 짝수 연속한 부분 수열
- node 버전 마이그레이션
- 서비스 디자인 패턴
- useCallback과 useMemo 사용
- nextjs errorboundary
- CSS
- node version yarn berry
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
글 보관함