From 59552f49d9c2722718d781a078a22ff26f410720 Mon Sep 17 00:00:00 2001 From: Jacob Ebey Date: Wed, 5 Jul 2023 12:18:20 -0700 Subject: [PATCH] - handle promise rejection - notify after reload check to avoid any extra pending HMR work --- packages/remix-react/browser.tsx | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/remix-react/browser.tsx b/packages/remix-react/browser.tsx index af38de51f6a..65b394692cb 100644 --- a/packages/remix-react/browser.tsx +++ b/packages/remix-react/browser.tsx @@ -56,6 +56,10 @@ let hmrRouterReadyPromise = new Promise((resolve) => { // body of a promise is executed immediately, so this can be resolved outside // of the promise body hmrRouterReadyResolve = resolve; +}).catch(() => { + // This is a noop catch handler to avoid unhandled promise rejection warnings + // in the console. The promise is never rejected. + return undefined; }); if (import.meta && import.meta.hot) { @@ -68,7 +72,15 @@ if (import.meta && import.meta.hot) { assetsManifest: EntryContext["manifest"]; needsRevalidation: Set; }) => { - const router = await hmrRouterReadyPromise; + let router = await hmrRouterReadyPromise; + // This should never happen, but just in case... + if (!router) { + console.error( + "Failed to accept HMR update because the router was not ready." + ); + return; + } + let routeIds = [ ...new Set( router.state.matches @@ -190,8 +202,7 @@ export function RemixBrowser(_props: RemixBrowserProps): ReactElement { window.__remixContext.future.v2_normalizeFormMethod, }, }); - hmrRouterReadyResolve?.(router); - + // Hard reload if the path we tried to load is not the current path. // This is usually the result of 2 rapid back/forward clicks from an // external site into a Remix app, where we initially start the load for @@ -208,6 +219,11 @@ export function RemixBrowser(_props: RemixBrowserProps): ReactElement { console.error(errorMsg); window.location.reload(); } + + // Notify that the router is ready for HMR + if (hmrRouterReadyResolve) { + hmrRouterReadyResolve(router); + } } let [location, setLocation] = React.useState(router.state.location);