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

[Bug]: lazy loaded module error in nested router is catched only by the parent route with the * wildcard, not by the errorElement in the nested router #11404

Open
artuska opened this issue Apr 3, 2024 · 2 comments
Labels

Comments

@artuska
Copy link

artuska commented Apr 3, 2024

What version of React Router are you using?

6.22.3

Steps to Reproduce

I use microfrontend architecture in my app. I have a RouteProvider in my host app with the createBrowserRouter router routes which have an * wildcard in their path:

host-app.router.ts

const Settings = lazy(() => import('microfrontend_settings/App'));

export const HostRouter = () => {
  const router = createBrowserRouter([
    {
      path: '/settings/*',
      element: <Settings />,
      errorElement: <HostErrorLayout />,
    },
  ],
  {
    basename: '/',
  });

  return (
    <RouterProvider router={router} />
  );
};

In my remote Settings app I also have a routing but I cannot use RouterProvider there because there must be only one router provider per whole app. Also, in my remote Settings app I cannot use createBrowserRouter router, because such a router needs its own provider, but as I mentioned previously, I cannot use nested router providers.

So in remote Settings app I use just <Routes> (without <BrowserRouter> component):

remote-settings-app.router.ts

const Notifications = lazy(() => import('microfrontend_settings_notifications/App'));
const Transactions = lazy(() => import('microfrontend_settings_transactions/App'));

export const RemoteRouter = () => {
  return (
    <Routes>
      <Route
        element={
          <SuspenseLayout fallback={SkeletonLayout}>
            <DefaultLayout />
          </SuspenseLayout>
        }
        errorElement={<RemoteErrorLayout />}
      >
        <Route
          path="notifications"
          element={<Notifications />}
        />

        ...

        <Route
          path="transactions"
          element={<Transactions />}
        />
    </Routes>
  );
};

So, my RemoteRouter is made with the <Routes> and is located inside the HostRouter which is made with the createBrowserRouter.

In order to remote Settings app router work I use a * wildcard in my host app /settings/* route — now my microfrontend app is displaying on /settings/notifications page correctly.

I made my Transactions app broken by purpose — remoteEntry.js file just does not exist on the server, so lazy loaded module throws an 404 error: Failed to fetch dynamically imported module.

So, the problem is now if I navigate to the /settings/transactions page the error will be displayed in my HostErrorLayout component — my RemoteErrorLayout in RemoteRouter will be just skipped and not catching an error.

Expected Behavior

Error bubbling should respect every route tree errorElement on any route tree level.

Actual Behavior

Error bubbling respects only root route's errorElement if the route has * wildcard.

@artuska artuska added the bug label Apr 3, 2024
@artuska
Copy link
Author

artuska commented Apr 3, 2024

I have tried to put an <Outlet /> component in my host app errorElement component, but it seems error element just does not respect a router outlet.

@artuska
Copy link
Author

artuska commented Apr 3, 2024

So, there is no any difference what level deep is nested my microfrontend routing — now I have Host app → remote Settings app → remote Integrations app → remote API app, all of the remotes are nested and have its own <Routes> inside and all of them have an errorElement.

So, when I break in purpose my remote API app I expect either Integrations app or Settings app will catch bubbled error but this does not happen — error bubbles to the main root router.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant