From 879e1358eff3e71a933c4df3ebe6b0032dcee79a Mon Sep 17 00:00:00 2001 From: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> Date: Mon, 10 Oct 2022 12:18:37 +0200 Subject: [PATCH] feat: frontend app error boundary (#2144) * feat: frontend app error boundary * fix: freeze added dependency * update yarn lock --- frontend/package.json | 5 +- frontend/src/component/App.tsx | 76 +++++++++++-------- frontend/src/component/layout/Error/Error.tsx | 44 +++++++++++ .../useInviteTokens/useInviteTokens.ts | 2 +- frontend/yarn.lock | 2 +- 5 files changed, 92 insertions(+), 37 deletions(-) create mode 100644 frontend/src/component/layout/Error/Error.tsx diff --git a/frontend/package.json b/frontend/package.json index 09e492e946..96e9059c81 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -61,6 +61,7 @@ "date-fns": "2.29.3", "debounce": "1.2.1", "deep-diff": "1.0.2", + "dequal": "2.0.3", "eslint": "8.23.0", "eslint-config-react-app": "7.0.1", "fast-json-patch": "3.1.1", @@ -76,6 +77,7 @@ "react": "17.0.2", "react-chartjs-2": "4.3.1", "react-dom": "17.0.2", + "react-error-boundary": "3.1.4", "react-hooks-global-state": "2.0.0", "react-router-dom": "6.3.0", "react-table": "7.8.0", @@ -128,8 +130,5 @@ "ignorePatterns": [ "cypress" ] - }, - "dependencies": { - "dequal": "2.0.3" } } diff --git a/frontend/src/component/App.tsx b/frontend/src/component/App.tsx index a3706268bf..c4c037fe65 100644 --- a/frontend/src/component/App.tsx +++ b/frontend/src/component/App.tsx @@ -1,4 +1,7 @@ +import { Suspense } from 'react'; import { Navigate, Route, Routes } from 'react-router-dom'; +import { ErrorBoundary } from 'react-error-boundary'; +import { Error } from 'component/layout/Error/Error'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { FeedbackNPS } from 'component/feedback/FeedbackNPS/FeedbackNPS'; import { LayoutPicker } from 'component/layout/LayoutPicker/LayoutPicker'; @@ -14,7 +17,6 @@ import { SplashPageRedirect } from 'component/splash/SplashPageRedirect/SplashPa import { useStyles } from './App.styles'; import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; -import { Suspense } from 'react'; export const App = () => { const { classes: styles } = useStyles(); @@ -29,40 +31,50 @@ export const App = () => { : routes; return ( - - }> - } - elseShow={ - - - - - {availableRoutes.map(route => ( + + + }> + } + elseShow={ + + + + + {availableRoutes.map(route => ( + + } + /> + ))} + } /> - ))} - - } - /> - } /> - - - - - - } - /> - - + } + /> + + + + + + } + /> + + + ); }; diff --git a/frontend/src/component/layout/Error/Error.tsx b/frontend/src/component/layout/Error/Error.tsx new file mode 100644 index 0000000000..826cb1f38f --- /dev/null +++ b/frontend/src/component/layout/Error/Error.tsx @@ -0,0 +1,44 @@ +import { VFC } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Box, Typography } from '@mui/material'; +import { Dialogue } from 'component/common/Dialogue/Dialogue'; +import { GO_BACK } from 'constants/navigate'; +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; + +interface IErrorProps { + error: Error; +} + +export const Error: VFC = ({ error }) => { + const navigate = useNavigate(); + return ( + + { + navigate('/'); + window?.location?.reload(); + }} + secondaryButtonText="Reload this page" + onClose={() => { + window?.location?.reload(); + }} + maxWidth="xl" + > + + {error.message} + + + {error.stack} + + } + /> + + + ); +}; diff --git a/frontend/src/hooks/api/getters/useInviteTokens/useInviteTokens.ts b/frontend/src/hooks/api/getters/useInviteTokens/useInviteTokens.ts index 2866dac412..654bd30e77 100644 --- a/frontend/src/hooks/api/getters/useInviteTokens/useInviteTokens.ts +++ b/frontend/src/hooks/api/getters/useInviteTokens/useInviteTokens.ts @@ -22,7 +22,7 @@ export const useInviteTokens = (options: SWRConfiguration = {}) => { return { data: data - ? { tokens: data.tokens.filter(token => token.enabled) } + ? { tokens: data.tokens?.filter(token => token.enabled) } : undefined, error, loading, diff --git a/frontend/yarn.lock b/frontend/yarn.lock index d70743b5a9..0c4f451cb2 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -5920,7 +5920,7 @@ react-dom@17.0.2: object-assign "^4.1.1" scheduler "^0.20.2" -react-error-boundary@^3.1.0: +react-error-boundary@3.1.4, react-error-boundary@^3.1.0: version "3.1.4" resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0" integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==