Skip to content

Commit 37a9a67

Browse files
authored
Merge pull request #198 from prgrms-web-devcourse-final-project/feat/191-error-boundary
[feat] error boundary 추가
2 parents d6360d2 + 2d865c2 commit 37a9a67

File tree

8 files changed

+97
-21
lines changed

8 files changed

+97
-21
lines changed

dev-dist/sw.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
7979
*/
8080
workbox.precacheAndRoute([{
8181
"url": "index.html",
82-
"revision": "0.koc340e0a3g"
82+
"revision": "0.08jje88gm9"
8383
}], {});
8484
workbox.cleanupOutdatedCaches();
8585
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {

package-lock.json

Lines changed: 13 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"lottie-react": "^2.4.1",
2424
"react": "^19.0.0",
2525
"react-dom": "^19.0.0",
26+
"react-error-boundary": "^5.0.0",
2627
"react-intersection-observer": "^9.15.1",
2728
"react-router": "^7.1.5",
2829
"react-spinners": "^0.15.0",

src/components/ErrorBoundary.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import ErrorFallback from '@/components/ErrorFallback';
2+
import { ErrorBoundary } from 'react-error-boundary';
3+
4+
const logError = (error: Error, info: React.ErrorInfo) => {
5+
console.error(error, info);
6+
// error: 발생한 에러 객체
7+
// info: 추가 정보 (어떤 컴포넌트에서 발생했는지)
8+
};
9+
10+
export default function MyErrorBoundary({ children }: { children: React.ReactNode }) {
11+
return (
12+
<ErrorBoundary FallbackComponent={ErrorFallback} onError={logError}>
13+
{children}
14+
</ErrorBoundary>
15+
);
16+
}

src/components/ErrorFallback.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import ErrorPage from '@/components/ErrorPage';
2+
3+
interface ErrorFallbackProps {
4+
error: Error;
5+
resetErrorBoundary: () => void;
6+
}
7+
8+
export default function ErrorFallback({ error, resetErrorBoundary }: ErrorFallbackProps) {
9+
console.log(error);
10+
11+
return (
12+
<ErrorPage
13+
title="500 Server Error"
14+
message={['서비스 이용에 불편을 드려 죄송합니다.', '잠시 후 다시 시도해 주세요.']}
15+
onClick={resetErrorBoundary}
16+
buttonText="다시 시도하기"
17+
/>
18+
);
19+
}

src/components/ErrorPage.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import Button from '@/components/Button';
2+
import sad from '@/assets/icons/sad-icon.svg';
3+
4+
interface ErrorPageProps {
5+
title: string;
6+
message: string | string[];
7+
onClick: (e: React.MouseEvent<HTMLButtonElement, MouseEvent> | undefined) => void;
8+
buttonText: string;
9+
}
10+
11+
const messageText = (message: string | string[]) => {
12+
if (Array.isArray(message)) return message.map((text, index) => <p key={index}>{text}</p>);
13+
return <p>{message}</p>;
14+
};
15+
16+
export default function ErrorPage({ title, message, onClick, buttonText }: ErrorPageProps) {
17+
return (
18+
<div className="relative w-full max-w-[600px] px-3 bg-background flex flex-col justify-center items-center">
19+
<div className="flex flex-col gap-5 justify-center items-center">
20+
<p className="text-[28px] font-bold text-primary-normal">{title}</p>
21+
<div className="flex flex-col justify-center items-center text-gray-60">
22+
{messageText(message)}
23+
</div>
24+
<img src={sad} className="w-[80px] h-[80px]" alt="sad" />
25+
</div>
26+
27+
<div className="absolute bottom-10 flex px-3 w-full">
28+
<Button onClick={onClick} variant="primary">
29+
{buttonText}
30+
</Button>
31+
</div>
32+
</div>
33+
);
34+
}

src/layouts/Layout.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import HeaderWithBack from '@/layouts/header/HeaderWithBack';
55
import HeaderChat from '@/layouts/header/HeaderChat';
66
import { twMerge } from 'tailwind-merge';
77
import PostButton from '@/components/PostButton';
8+
import MyErrorBoundary from '@/components/ErrorBoundary';
89
import { useEffect, useRef } from 'react';
910
import { useScrollStore } from '@/store/scrollStore';
1011

@@ -77,7 +78,9 @@ function Layout() {
7778
showNav && 'pb-[62px] ', // 하단 네비게이션 숨길때만 padding주기
7879
)}
7980
>
80-
<Outlet />
81+
<MyErrorBoundary>
82+
<Outlet />
83+
</MyErrorBoundary>
8184
</div>
8285

8386
{/* 하단 네비게이션 */}

src/pages/NotFound.tsx

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
1-
import Button from '@/components/Button';
2-
import sad from '@/assets/icons/sad-icon.svg';
1+
import ErrorPage from '@/components/ErrorPage';
2+
import { useNavigate } from 'react-router';
33

44
export default function NotFound() {
5+
const navigate = useNavigate();
56
return (
6-
<div className="relative w-full max-w-[600px] px-3 bg-background flex flex-col justify-center items-center">
7-
<div className="flex flex-col gap-5 justify-center items-center">
8-
<p className="text-[28px] font-bold text-primary-normal">404 Not Found</p>
9-
<div className="flex flex-col justify-center items-center text-gray-60">
10-
<p>페이지를 찾을 수 없어요</p>
11-
<p>새로운 감정을 발견하러 가볼까요?</p>
12-
</div>
13-
14-
<img src={sad} className="w-[80px] h-[80px]" alt="sad" />
15-
</div>
16-
17-
<div className="absolute bottom-10 flex px-3 w-full">
18-
<Button variant="primary">홈으로 가기</Button>
19-
</div>
20-
</div>
7+
<ErrorPage
8+
title="404 Not Found"
9+
message={['페이지를 찾을 수 없어요', '새로운 감정을 발견하러 가볼까요?']}
10+
onClick={() => navigate('/')}
11+
buttonText="홈으로 가기"
12+
/>
2113
);
2214
}

0 commit comments

Comments
 (0)