Skip to content

Commit

Permalink
[Feature]: 에러핸들러 동작방식 수정, sentry 에러잡기 테스트 (#102)
Browse files Browse the repository at this point in the history
* feat: custom error 핸들러 추가

* feat: sentry 에러 잡는 Async component 생성

* feat: 404 페이지 생성

* feat: 404 페이지 404 잡히게끔 설정

* fix: Text 잘못 import 한것 제거

* feat: apiErrorboundary 수정
  • Loading branch information
eugene028 authored Aug 22, 2024
1 parent 097e232 commit 140dbf4
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 10 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@
"nanoid": "^5.0.7",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^4.0.13",
"react-hook-form": "^7.50.1",
"react-router-dom": "^6.22.1",
"react-toastify": "^10.0.4",
"wowds-icons": "^0.1.0",
"wowds-tokens": "^0.0.9",
"zustand": "^4.5.0",
"wowds-ui": "^0.1.9"
"wowds-ui": "^0.1.9",
"zustand": "^4.5.0"
},
"devDependencies": {
"@sentry/react": "^8.22.0",
Expand Down
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added public/notfound.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 25 additions & 4 deletions src/components/ApiErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import { PropsWithChildren } from 'react';

import { PropsWithChildren, PropsWithRef } from 'react';
import * as Sentry from '@sentry/react';
import { ErrorBoundary } from 'react-error-boundary';
import { useQueryClient } from '@tanstack/react-query';
import { AxiosError } from 'axios';
import { redirect } from 'react-router-dom';
import { toast } from 'react-toastify';
import RoutePath from '@/routes/routePath';
import NotFoundPage from '@/pages/NotFound';

type ErrorResponseType = {
errorCodeName: string;
errorMessage: string;
};

export default function ApiErrorBoundary({ children }: PropsWithChildren) {
export type ApiErrorBoundaryProps = PropsWithRef<
PropsWithChildren<ErrorBoundary>
>;

export default function ApiErrorBoundary({
children,
...rest
}: ApiErrorBoundaryProps) {
const queryClient = useQueryClient();

queryClient.getQueryCache().config = {
Expand All @@ -38,7 +47,19 @@ export default function ApiErrorBoundary({ children }: PropsWithChildren) {
toast.error(message);
break;
}

if (errorResponse) {
// eslint-disable-next-line import/namespace
Sentry.captureException(errorResponse, {});
}
}

return <>{children}</>;
return (
<ErrorBoundary
{...rest}
onError={(error) => handleError(error as AxiosError)}
fallbackRender={() => <NotFoundPage />}>
{children}
</ErrorBoundary>
);
}
15 changes: 15 additions & 0 deletions src/components/common/AsyncBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ErrorBoundary } from '@sentry/react';
import { Suspense, SuspenseProps } from 'react';
import LoadingSpinner from './LoadingSpinner';

type AsyncBoundaryProps = Omit<SuspenseProps, 'fallback'>;

const AsyncBoundary = ({ children, ...rest }: AsyncBoundaryProps) => {
return (
<ErrorBoundary {...rest}>
<Suspense fallback={<LoadingSpinner />}>{children}</Suspense>
</ErrorBoundary>
);
};

export default AsyncBoundary;
73 changes: 73 additions & 0 deletions src/pages/NotFound.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Flex, Space, Text } from '@/components/common/Wrapper';
import * as Sentry from '@sentry/react';
import GlobalSize from '@/constants/globalSize';
import { media } from '@/styles';
import styled from '@emotion/styled';
import { useNavigate } from 'react-router-dom';
import { color } from 'wowds-tokens';
import Button from 'wowds-ui/Button';

const NotFoundPage = () => {
const navigate = useNavigate();
if (process.env.NODE_ENV === 'production') {
// eslint-disable-next-line import/namespace
Sentry.captureMessage('404 Page Not Found', {
extra: {
pathname: location.pathname
}
});
}
return (
<NotfoundWrapper>
<Space height={100} />
<Flex gap="sm" direction="column">
<Img src={'/notfound.png'} width={300} height={50} />
<Text typo="h1">오류가 발생했어요.</Text>
<Text typo="body1">요청하신 페이지를 찾을 수 없어요.</Text>
</Flex>
<ButtonContainer>
<Button
style={{ maxWidth: '100%' }}
onClick={() => {
navigate('/');
}}>
메인 화면으로 돌아가기
</Button>
</ButtonContainer>
</NotfoundWrapper>
);
};

export default NotFoundPage;

const Img = styled.img`
object-fit: cover;
`;

const NotfoundWrapper = styled.div`
display: flex;
position: relative;
flex-direction: column;
justify-content: start;
align-items: center;
min-height: calc(100vh - ${GlobalSize.header});
width: ${GlobalSize.width};
margin: 0px -16px;
padding: 0px 16px;
padding-top: 40px;
padding-bottom: 28px;
background-color: ${color.backgroundAlternative};
${media.mobile} {
width: 100vw;
}
`;

const ButtonContainer = styled.div`
position: absolute;
bottom: 1.75rem;
padding: 1rem 0.75rem;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
`;
1 change: 1 addition & 0 deletions src/pages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export * from './redirect/StudentVerificationServerRedirect';
export * from './PaymentsCheckout';
export * from './PaymentsFail';
export * from './PaymentsSuccess';
export * from './NotFound';
8 changes: 5 additions & 3 deletions src/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import RoutePath from '@/routes/routePath';
import { RouterProvider, createBrowserRouter } from 'react-router-dom';
import Layout from '@/components/layout/Layout';
import AuthAccessGuard from '@/components/auth/guard/AuthAccessGuard';
import { Text } from '@/components/common/Wrapper';
import NotFoundPage from '@/pages/NotFound';
import {
AuthServerRedirectNavigate,
StudentVerificationServerRedirect,
Expand Down Expand Up @@ -148,8 +148,10 @@ const router = sentryCreateBrowserRouter([
path: RoutePath.PaymentsSuccess,
element: <PaymentsSuccess />
},
// Todo: 404 Not found page
{ path: '*', element: <Text>not found page</Text> }
{
path: '*',
element: <NotFoundPage />
}
]
}
]);
1 change: 0 additions & 1 deletion src/utils/sentry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const setSentry = () => {
function initSentry() {
if (process.env.NODE_ENV === 'development') return;

console.log(`VERCEL ENV : ${process.env.VERCEL_ENV}`);
Sentry.init({
environment: process.env.VERCEL_ENV,
dsn: SENTRY_DSN_KEY,
Expand Down

0 comments on commit 140dbf4

Please sign in to comment.