Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a global lazyLoading error handling #7227

Merged
merged 9 commits into from
Nov 22, 2024
Prev Previous commit
Next Next commit
Translations
  • Loading branch information
ccanos committed Nov 21, 2024
commit 09038abbd02c7d3a226448ca36957121aba6f0a0
5 changes: 4 additions & 1 deletion src/core/i18n/en/translation.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2557,7 +2557,10 @@
"buttons": {
"reload": "Reload"
},
"dynamicError": "Network error occurred. Please try reloading the page."
"errors": {
"LazyLoadError": "Network error occurred. Please try reloading the page.",
"unknown": "An unknown error occurred. Please try reloading the page."
}
},
"four-ou-four": {
"title": "Something went wrong...",
Expand Down
13 changes: 10 additions & 3 deletions src/core/lazyLoading/GlobalErrorDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ import { Box, Button, Dialog, DialogContent } from '@mui/material';
import { useGlobalError } from './GlobalErrorContext';
import DialogHeader from '../ui/dialog/DialogHeader';
import { BlockTitle } from '../ui/typography';
import { LazyLoadError } from './lazyWithGlobalErrorHandler';
import TranslationKey from '../i18n/utils/TranslationKey';

const ErrorTranslationMapppings = (error: Error): TranslationKey => {
if (error instanceof LazyLoadError) {
return 'pages.error.errors.LazyLoadError';
}
return 'pages.error.errors.unknown';
};

export const GlobalErrorDialog: React.FC = () => {
const { t } = useTranslation();
Expand All @@ -21,9 +30,7 @@ export const GlobalErrorDialog: React.FC = () => {
<Trans
i18nKey="pages.error.line1"
values={{
message: error.message?.toLowerCase().includes('failed to fetch dynamically imported module')
? t('pages.error.dynamicError')
: null,
message: t(ErrorTranslationMapppings(error)),
}}
components={{
italic: <i />,
Expand Down
28 changes: 17 additions & 11 deletions src/core/lazyLoading/lazyWithGlobalErrorHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ import { getGlobalErrorSetter } from './GlobalErrorContext';

type ImportFunc<T> = () => Promise<{ default: React.ComponentType<T> }>;

export class LazyLoadError extends Error {
constructor(originalError: Error) {
super(originalError.message);
this.name = 'LazyLoadError';
Object.setPrototypeOf(this, LazyLoadError.prototype);
}
}

export const lazyWithGlobalErrorHandler = <T>(
importFunc: ImportFunc<T>
): React.LazyExoticComponent<React.ComponentType<T>> => {
Expand All @@ -11,7 +19,10 @@ export const lazyWithGlobalErrorHandler = <T>(
return await importFunc();
} catch (error) {
const setError = getGlobalErrorSetter();
setError(error as Error);
const originalError: Error =
error instanceof Error ? error : error?.['message'] ? new Error(error['message']) : new Error('Unknown error');

setError(new LazyLoadError(originalError));

// it looks like this error is already logged by the useErrorLoggerLink (network error)

Expand All @@ -24,20 +35,15 @@ export const lazyWithGlobalErrorHandler = <T>(
});
};

class ContentUnavailableError extends Error {
constructor(message: string) {
super(message);
this.name = 'ContentUnavailableError';
Object.setPrototypeOf(this, ContentUnavailableError.prototype);
}
}

export const lazyImportWithErrorHandler = async <T>(importFunc: () => Promise<T>): Promise<T> => {
try {
return await importFunc();
} catch (error) {
const setError = getGlobalErrorSetter();
setError(error as Error);
throw new ContentUnavailableError((error as Error)?.message);
const originalError: Error =
error instanceof Error ? error : error?.['message'] ? new Error(error['message']) : new Error('Unknown error');

setError(new LazyLoadError(originalError));
throw new LazyLoadError(originalError);
}
};