From 344e9a83e4c452b8252d92cb708fe7d052939296 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Mon, 15 Dec 2025 17:13:49 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=A5=85(frontend)=20add=20boundary=20error?= =?UTF-8?q?=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a custom error page to handle unexpected errors gracefully. This page provides users with options to navigate back to the home page or refresh the current page, enhancing the overall user experience during error scenarios. It is quite hard to test this page, it cannot be trigger in development mode, we have to build the app and have a real error in production to see it. --- CHANGELOG.md | 1 + .../src/assets/icons/error-planetes.png | Bin 0 -> 28296 bytes .../apps/impress/src/components/Box.tsx | 6 +- .../components/LeftPanelContent.tsx | 4 +- .../components/LeftPanelDocContent.tsx | 10 +- src/frontend/apps/impress/src/pages/404.tsx | 36 +++-- .../apps/impress/src/pages/_error.tsx | 126 ++++++++++++++++++ 7 files changed, 163 insertions(+), 20 deletions(-) create mode 100644 src/frontend/apps/impress/src/assets/icons/error-planetes.png create mode 100644 src/frontend/apps/impress/src/pages/_error.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 35eed1e3..2defd1da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to - ✨(backend) add async indexation of documents on save (or access save) #1276 - ✨(backend) add debounce mechanism to limit indexation jobs #1276 - ✨(api) add API route to search for indexed documents in Find #1276 +- 🥅(frontend) add boundary error page #1728 ### Changed diff --git a/src/frontend/apps/impress/src/assets/icons/error-planetes.png b/src/frontend/apps/impress/src/assets/icons/error-planetes.png new file mode 100644 index 0000000000000000000000000000000000000000..e8cffbdbb5da237aef8eea0537efeb6d3ddfa6fc GIT binary patch literal 28296 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 ${({ $display, as }) => `display: ${$display || (as?.match('span|input') ? 'inline-flex' : 'flex')};`} ${({ $flex }) => $flex && `flex: ${$flex};`} - ${({ $gap }) => $gap && `gap: ${$gap};`} + ${({ $gap }) => $gap && `gap: ${spacingValue($gap)};`} ${({ $height }) => $height && `height: ${$height};`} ${({ $hasTransition }) => $hasTransition && $hasTransition === 'slow' diff --git a/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelContent.tsx b/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelContent.tsx index 98f04e8b..112bf36e 100644 --- a/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelContent.tsx +++ b/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelContent.tsx @@ -2,6 +2,7 @@ import { useRouter } from 'next/router'; import { css } from 'styled-components'; import { Box, SeparatedSection } from '@/components'; +import { useDocStore } from '@/docs/doc-management'; import { LeftPanelTargetFilters } from './LefPanelTargetFilters'; import { LeftPanelDocContent } from './LeftPanelDocContent'; @@ -11,6 +12,7 @@ export const LeftPanelContent = () => { const router = useRouter(); const isHome = router.pathname === '/'; const isDoc = router.pathname === '/docs/[id]'; + const { currentDoc } = useDocStore(); return ( <> @@ -36,7 +38,7 @@ export const LeftPanelContent = () => { )} - {isDoc && } + {isDoc && currentDoc && } ); }; diff --git a/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelDocContent.tsx b/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelDocContent.tsx index 6e67f8a9..3f7f2536 100644 --- a/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelDocContent.tsx +++ b/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelDocContent.tsx @@ -1,15 +1,13 @@ import { useTreeContext } from '@gouvfr-lasuite/ui-kit'; import { Box } from '@/components'; -import { Doc, useDocStore } from '@/docs/doc-management'; +import { Doc } from '@/docs/doc-management'; import { DocTree } from '@/docs/doc-tree/'; -export const LeftPanelDocContent = () => { - const { currentDoc } = useDocStore(); - +export const LeftPanelDocContent = ({ doc }: { doc: Doc }) => { const tree = useTreeContext(); - if (!currentDoc || !tree) { + if (!tree) { return null; } @@ -20,7 +18,7 @@ export const LeftPanelDocContent = () => { $css="width: 100%; overflow-y: auto; overflow-x: hidden;" className="--docs--left-panel-doc-content" > - + ); }; diff --git a/src/frontend/apps/impress/src/pages/404.tsx b/src/frontend/apps/impress/src/pages/404.tsx index 739fe9b6..a7b61099 100644 --- a/src/frontend/apps/impress/src/pages/404.tsx +++ b/src/frontend/apps/impress/src/pages/404.tsx @@ -5,7 +5,7 @@ import { ReactElement } from 'react'; import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; -import img403 from '@/assets/icons/icon-403.png'; +import error_img from '@/assets/icons/error-planetes.png'; import { Box, Icon, StyledLink, Text } from '@/components'; import { PageLayout } from '@/layouts'; import { NextPageWithLayout } from '@/types/next'; @@ -32,32 +32,46 @@ const Page: NextPageWithLayout = () => { {t('Page Not Found - Error 404')} - {t('Docs')} - - - {t( - 'It seems that the page you are looking for does not exist or cannot be displayed correctly.', - )} - + + {t( + 'It seems that the page you are looking for does not exist or cannot be displayed correctly.', + )} + + - }> + + } + > {t('Home')} diff --git a/src/frontend/apps/impress/src/pages/_error.tsx b/src/frontend/apps/impress/src/pages/_error.tsx new file mode 100644 index 00000000..65aa0647 --- /dev/null +++ b/src/frontend/apps/impress/src/pages/_error.tsx @@ -0,0 +1,126 @@ +import { Button } from '@openfun/cunningham-react'; +import * as Sentry from '@sentry/nextjs'; +import { NextPageContext } from 'next'; +import NextError from 'next/error'; +import Head from 'next/head'; +import Image from 'next/image'; +import { ReactElement } from 'react'; +import { useTranslation } from 'react-i18next'; +import styled from 'styled-components'; + +import error_img from '@/assets/icons/error-planetes.png'; +import { Box, Icon, StyledLink, Text } from '@/components'; +import { PageLayout } from '@/layouts'; + +const StyledButton = styled(Button)` + width: fit-content; +`; + +const Error = () => { + const { t } = useTranslation(); + + const errorTitle = t('An unexpected error occurred.'); + + return ( + <> + + + {errorTitle} - {t('Docs')} + + + + + + {errorTitle} - {t('Docs')} + + + + + {errorTitle} + + + + + + } + > + {t('Home')} + + + + + } + onClick={() => window.location.reload()} + > + {t('Refresh page')} + + + + + ); +}; + +Error.getInitialProps = async (contextData: NextPageContext) => { + const { res, err, asPath, pathname, query } = contextData; + + Sentry.captureException(err, { + contexts: { + nextjs: { + page: pathname, + path: asPath, + query: query, + statusCode: res?.statusCode || err?.statusCode, + }, + }, + tags: { + errorPage: '_error.tsx', + statusCode: String(res?.statusCode || err?.statusCode || 'unknown'), + }, + }); + + return NextError.getInitialProps(contextData); +}; + +Error.getLayout = function getLayout(page: ReactElement) { + return {page}; +}; + +export default Error;