Skip to content

Commit

Permalink
Merge pull request #45596 from pasyukevich/fix/import-rerty-error
Browse files Browse the repository at this point in the history
[No QA] fix retry import error
  • Loading branch information
dangrous authored Jul 24, 2024
2 parents 46184d0 + c3cbd78 commit bf69d5d
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5166,6 +5166,7 @@ const CONST = {
SESSION_STORAGE_KEYS: {
INITIAL_URL: 'INITIAL_URL',
ACTIVE_WORKSPACE_ID: 'ACTIVE_WORKSPACE_ID',
RETRY_LAZY_REFRESHED: 'RETRY_LAZY_REFRESHED',
},

RESERVATION_TYPE: {
Expand Down
5 changes: 3 additions & 2 deletions src/libs/Navigation/AppNavigator/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import React, {lazy, memo, Suspense, useContext, useEffect} from 'react';
import {NativeModules} from 'react-native';
import {InitialURLContext} from '@components/InitialURLContextProvider';
import Navigation from '@libs/Navigation/Navigation';
import lazyRetry from '@src/utils/lazyRetry';

const AuthScreens = lazy(() => import('./AuthScreens'));
const PublicScreens = lazy(() => import('./PublicScreens'));
const AuthScreens = lazy(() => lazyRetry(() => import('./AuthScreens')));
const PublicScreens = lazy(() => lazyRetry(() => import('./PublicScreens')));

type AppNavigatorProps = {
/** If we have an authToken this is true */
Expand Down
42 changes: 42 additions & 0 deletions src/utils/lazyRetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type {ComponentType} from 'react';
import CONST from '@src/CONST';

type Import<T> = Promise<{default: T}>;
type ComponentImport<T> = () => Import<T>;

/**
* Attempts to lazily import a React component with a retry mechanism on failure.
* If the initial import fails the function will refresh the page once and retry the import.
* If the import fails again after the refresh, the error is propagated.
*
* @param componentImport - A function that returns a promise resolving to a lazily imported React component.
* @returns A promise that resolves to the imported component or rejects with an error after a retry attempt.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const lazyRetry = function <T extends ComponentType<any>>(componentImport: ComponentImport<T>): Import<T> {
return new Promise((resolve, reject) => {
// Retrieve the retry status from sessionStorage, defaulting to 'false' if not set
const hasRefreshed = JSON.parse(sessionStorage.getItem(CONST.SESSION_STORAGE_KEYS.RETRY_LAZY_REFRESHED) ?? 'false') as boolean;

componentImport()
.then((component) => {
// Reset the retry status to 'false' on successful import
sessionStorage.setItem(CONST.SESSION_STORAGE_KEYS.RETRY_LAZY_REFRESHED, 'false'); // success so reset the refresh
resolve(component);
})
.catch((component: ComponentImport<T>) => {
if (!hasRefreshed) {
console.error('Failed to lazily import a React component, refreshing the page in order to retry the operation.', component);
// Set the retry status to 'true' and refresh the page
sessionStorage.setItem(CONST.SESSION_STORAGE_KEYS.RETRY_LAZY_REFRESHED, 'true');
window.location.reload(); // Refresh the page to retry the import
} else {
console.error('Failed to lazily import a React component after the retry operation!', component);
// If the import fails again reject with the error to trigger default error handling
reject(component);
}
});
});
};

export default lazyRetry;

0 comments on commit bf69d5d

Please sign in to comment.