[fix] Fix white screen when error handled by AppErrorBoundary (#5017)

[In a previous PR](https://github.com/twentyhq/twenty/pull/5008) I was
fixing dark mode by calling useTheme in AppErrorBoundary while there was
actually no parent ThemeProvider. This was causing a bug when an error
was actually intercepted by AppErrorBoundary because theme was empty.

Now I am providing the error theme in GenericErrorFallback, fallbacking
to THEME_LIGHT as it can be called from outside a ThemeProvider (as it
is the case today), but also reading into ThemeProvider in case we end
up using this component in a part of the application where it is
available, not to necessarily use THEME_LIGHT.

## How was it tested?
with @thaisguigon 
Locally (dark mode works + error mode works (throwing an error in
RecoilDebugObserver))
This commit is contained in:
Marie
2024-04-18 10:42:30 +02:00
committed by GitHub
parent 03e0fd2a65
commit 3e60c0050c
2 changed files with 29 additions and 29 deletions

View File

@ -1,6 +1,5 @@
import { ErrorInfo, ReactNode } from 'react'; import { ErrorInfo, ReactNode } from 'react';
import { ErrorBoundary } from 'react-error-boundary'; import { ErrorBoundary } from 'react-error-boundary';
import { ThemeProvider, useTheme } from '@emotion/react';
import { GenericErrorFallback } from '@/error-handler/components/GenericErrorFallback'; import { GenericErrorFallback } from '@/error-handler/components/GenericErrorFallback';
@ -9,16 +8,12 @@ export const AppErrorBoundary = ({ children }: { children: ReactNode }) => {
// TODO: log error to Sentry // TODO: log error to Sentry
}; };
const theme = useTheme();
return ( return (
<ThemeProvider theme={theme}> <ErrorBoundary
<ErrorBoundary FallbackComponent={GenericErrorFallback}
FallbackComponent={GenericErrorFallback} onError={handleError}
onError={handleError} >
> {children}
{children} </ErrorBoundary>
</ErrorBoundary>
</ThemeProvider>
); );
}; };

View File

@ -1,5 +1,7 @@
import { FallbackProps } from 'react-error-boundary'; import { FallbackProps } from 'react-error-boundary';
import { IconRefresh } from 'twenty-ui'; import { ThemeProvider, useTheme } from '@emotion/react';
import isEmpty from 'lodash.isempty';
import { IconRefresh, THEME_LIGHT } from 'twenty-ui';
import { Button } from '@/ui/input/button/components/Button'; import { Button } from '@/ui/input/button/components/Button';
import AnimatedPlaceholder from '@/ui/layout/animated-placeholder/components/AnimatedPlaceholder'; import AnimatedPlaceholder from '@/ui/layout/animated-placeholder/components/AnimatedPlaceholder';
@ -16,23 +18,26 @@ export const GenericErrorFallback = ({
error, error,
resetErrorBoundary, resetErrorBoundary,
}: GenericErrorFallbackProps) => { }: GenericErrorFallbackProps) => {
const theme = useTheme();
return ( return (
<AnimatedPlaceholderEmptyContainer> <ThemeProvider theme={isEmpty(theme) ? THEME_LIGHT : theme}>
<AnimatedPlaceholder type="errorIndex" /> <AnimatedPlaceholderEmptyContainer>
<AnimatedPlaceholderEmptyTextContainer> <AnimatedPlaceholder type="errorIndex" />
<AnimatedPlaceholderEmptyTitle> <AnimatedPlaceholderEmptyTextContainer>
Servers on a coffee break <AnimatedPlaceholderEmptyTitle>
</AnimatedPlaceholderEmptyTitle> Servers on a coffee break
<AnimatedPlaceholderEmptySubTitle> </AnimatedPlaceholderEmptyTitle>
{error.message} <AnimatedPlaceholderEmptySubTitle>
</AnimatedPlaceholderEmptySubTitle> {error.message}
</AnimatedPlaceholderEmptyTextContainer> </AnimatedPlaceholderEmptySubTitle>
<Button </AnimatedPlaceholderEmptyTextContainer>
Icon={IconRefresh} <Button
title="Reload" Icon={IconRefresh}
variant={'secondary'} title="Reload"
onClick={() => resetErrorBoundary()} variant={'secondary'}
/> onClick={() => resetErrorBoundary()}
</AnimatedPlaceholderEmptyContainer> />
</AnimatedPlaceholderEmptyContainer>
</ThemeProvider>
); );
}; };