Improve AppError boundaries (#11107)

## What

This PR aims to make sure all application exceptions are captured
through react-error-boundaries

Once merged we will have:
- Root Level: AppErrorBoundary at the highest level (full screen) ==>
this one needs to be working in any case, not relying on Theme, was not
working
- Route Level: AppErrorBoundary in DefaultLayout (full screen) ==> this
was missing and it seems that error are not propagated outside of the
router, making errors triggered in CommandMenu or NavigationDrawer
missing
- Page Level: AppErrorBoundary in DefaultLayout write around the Page
itself (lower than CommandMenu + NavigationDrawer)
- Manually triggered: example in ClientConfigProvider

## Screenshots

App level (ex throw in IconsProvider)
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/18a14815-a203-4edf-b931-43068c3436ec"
/>

Route level (ex throw in CommandMenu)
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/ca066627-14c7-438e-a432-f0999a1f3b84"
/>

Page level (ex throw in RecordTable)
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/ffeaa935-02af-4762-8859-7a0ccf8b77e1"
/>

Manually Triggered (clientConfig, ex when backend is not up)
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/062d6d84-097a-4ed9-b6ce-763b8c27c659"
/>
This commit is contained in:
Charles Bochet
2025-03-22 09:19:08 +01:00
committed by GitHub
parent c50cdd9510
commit 692e08f0d4
13 changed files with 341 additions and 162 deletions

View File

@ -1,6 +1,8 @@
import { AuthModal } from '@/auth/components/AuthModal';
import { CommandMenuRouter } from '@/command-menu/components/CommandMenuRouter';
import { AppErrorBoundary } from '@/error-handler/components/AppErrorBoundary';
import { AppFullScreenErrorFallback } from '@/error-handler/components/AppFullScreenErrorFallback';
import { AppPageErrorFallback } from '@/error-handler/components/AppPageErrorFallback';
import { KeyboardShortcutMenu } from '@/keyboard-shortcut-menu/components/KeyboardShortcutMenu';
import { AppNavigationDrawer } from '@/navigation/components/AppNavigationDrawer';
import { MobileNavigationBar } from '@/navigation/components/MobileNavigationBar';
@ -82,51 +84,52 @@ export const DefaultLayout = () => {
`}
/>
<StyledLayout>
{!showAuthModal && (
<>
<CommandMenuRouter />
<KeyboardShortcutMenu />
</>
)}
<StyledPageContainer
animate={{
marginLeft:
isSettingsPage && !isMobile && !useShowFullScreen
? (windowsWidth -
(OBJECT_SETTINGS_WIDTH +
NAV_DRAWER_WIDTHS.menu.desktop.expanded +
64)) /
2
: 0,
}}
transition={{ duration: theme.animation.duration.normal }}
>
{showAuthModal ? (
<StyledAppNavigationDrawerMock />
) : useShowFullScreen ? null : (
<StyledAppNavigationDrawer />
)}
{showAuthModal ? (
<>
<SignInBackgroundMockPage />
<AnimatePresence mode="wait">
<LayoutGroup>
<AuthModal>
<Outlet />
</AuthModal>
</LayoutGroup>
</AnimatePresence>
</>
) : (
<StyledMainContainer>
<AppErrorBoundary>
<Outlet />
</AppErrorBoundary>
</StyledMainContainer>
)}
</StyledPageContainer>
{isMobile && <MobileNavigationBar />}
<AppErrorBoundary FallbackComponent={AppFullScreenErrorFallback}>
<StyledPageContainer
animate={{
marginLeft:
isSettingsPage && !isMobile && !useShowFullScreen
? (windowsWidth -
(OBJECT_SETTINGS_WIDTH +
NAV_DRAWER_WIDTHS.menu.desktop.expanded +
64)) /
2
: 0,
}}
transition={{ duration: theme.animation.duration.normal }}
>
{!showAuthModal && (
<>
<CommandMenuRouter />
<KeyboardShortcutMenu />
</>
)}
{showAuthModal ? (
<StyledAppNavigationDrawerMock />
) : useShowFullScreen ? null : (
<StyledAppNavigationDrawer />
)}
{showAuthModal ? (
<>
<SignInBackgroundMockPage />
<AnimatePresence mode="wait">
<LayoutGroup>
<AuthModal>
<Outlet />
</AuthModal>
</LayoutGroup>
</AnimatePresence>
</>
) : (
<StyledMainContainer>
<AppErrorBoundary FallbackComponent={AppPageErrorFallback}>
<Outlet />
</AppErrorBoundary>
</StyledMainContainer>
)}
</StyledPageContainer>
{isMobile && <MobileNavigationBar />}
</AppErrorBoundary>
</StyledLayout>
</>
);