Drop redundant bootstrap error boundary
React Router routes render and loader errors to the route-level boundaries, so the App-level boundary above the router could only catch provider render failures — which today are trivial — while true bootstrap failures throw at module load before it mounts. Neither console nor trust wraps App this way. Rely on the root route boundary instead and remove the BootstrapError fallback it used. Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
@@ -18,19 +18,15 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
import { ErrorBoundary } from "@probo/ui/src/v2/ErrorBoundary/ErrorBoundary";
|
||||
import { RouterProvider } from "react-router";
|
||||
|
||||
import { BootstrapError } from "#/components/errors/BootstrapError";
|
||||
import { RelayProvider } from "#/lib/relay/RelayProvider";
|
||||
import { router } from "#/routes";
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<ErrorBoundary fallback={<BootstrapError />}>
|
||||
<RelayProvider>
|
||||
<RouterProvider router={router} />
|
||||
</RelayProvider>
|
||||
</ErrorBoundary>
|
||||
<RelayProvider>
|
||||
<RouterProvider router={router} />
|
||||
</RelayProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
import { Anchor } from "@probo/ui/src/v2/Button/Anchor";
|
||||
import { Button } from "@probo/ui/src/v2/Button/Button";
|
||||
import { ErrorState } from "@probo/ui/src/v2/ErrorState/ErrorState";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { getPathPrefix } from "#/lib/http/pathPrefix";
|
||||
|
||||
// Outermost fallback for failures that happen before (or in) the router itself.
|
||||
// It cannot use the router (no context yet), so navigation is a plain anchor and
|
||||
// recovery is a hard reload.
|
||||
export function BootstrapError() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<ErrorState
|
||||
fullPage
|
||||
title={t("errors.generic.title")}
|
||||
description={t("errors.generic.description")}
|
||||
actions={(
|
||||
<>
|
||||
<Anchor href={getPathPrefix() || "/"} variant="solid" color="neutral" highContrast size={2}>
|
||||
{t("errors.actions.backToTrustCenter")}
|
||||
</Anchor>
|
||||
<Button variant="soft" color="neutral" size={2} onClick={() => window.location.reload()}>
|
||||
{t("errors.actions.tryAgain")}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -61,7 +61,7 @@ interface GlobalErrorProps {
|
||||
}
|
||||
|
||||
// Page-level error fallback: renders the v2 ErrorState with portal copy and
|
||||
// actions. Used by the bootstrap boundary and the route boundaries.
|
||||
// actions. Used by the route boundaries (root + page).
|
||||
export function GlobalError({ error, onRetry, fullPage = false }: GlobalErrorProps) {
|
||||
const { t } = useTranslation();
|
||||
const { code, titleKey, descriptionKey } = resolveContent(error);
|
||||
|
||||
@@ -211,7 +211,7 @@ The portal ships three fallback tiers, all backed by the same `ErrorBoundary`:
|
||||
|
||||
| Tier | Placement | Fallback |
|
||||
|------|-----------|----------|
|
||||
| Global (bootstrap) | around `RouterProvider` in `App.tsx`, and the root route | `ErrorState` full page (standalone) |
|
||||
| Global | root route (`RootErrorBoundary`) | `ErrorState` full page (standalone) |
|
||||
| Page | pathless child route inside the layout | `ErrorState` inside the shell (TopBar/footer survive) |
|
||||
| Section / row | around a fragment-reading subtree | `InlineError` (vertical for sections, horizontal for rows) with a retry |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user