diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index 4b7a462c..b5a87c43 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -49,5 +49,10 @@ "connecting": "Connecting...", "installFreighter": "Install Freighter", "retry": "Retry" + }, + + "errorBoundary": { + "title": "Something went wrong. Please reload the page.", + "reload": "Reload" } } diff --git a/apps/web/messages/fr.json b/apps/web/messages/fr.json index ed6b5a1e..6e86515f 100644 --- a/apps/web/messages/fr.json +++ b/apps/web/messages/fr.json @@ -49,5 +49,10 @@ "connecting": "Connexion...", "installFreighter": "Installer Freighter", "retry": "Réessayer" + }, + + "errorBoundary": { + "title": "Une erreur s'est produite. Veuillez recharger la page.", + "reload": "Recharger" } } diff --git a/apps/web/src/__tests__/components/ErrorBoundary.test.tsx b/apps/web/src/__tests__/components/ErrorBoundary.test.tsx index aec794aa..a9da7fce 100644 --- a/apps/web/src/__tests__/components/ErrorBoundary.test.tsx +++ b/apps/web/src/__tests__/components/ErrorBoundary.test.tsx @@ -2,6 +2,16 @@ import { describe, it, expect, vi } from "vitest"; import { render, screen } from "@testing-library/react"; import { ErrorBoundary } from "../../components/ui/ErrorBoundary"; +vi.mock("react-i18next", () => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + withTranslation: () => (WrappedComponent: any) => { + function Wrapped(props: Record) { + return key} />; + } + return Wrapped; + }, +})); + function Bomb(): never { throw new Error("render panic"); } @@ -29,9 +39,8 @@ describe("ErrorBoundary", () => { ); - expect( - screen.getByText("Something went wrong. Please reload the page.") - ).toBeDefined(); + expect(screen.getByText("errorBoundary.title")).toBeDefined(); + expect(screen.getByText("errorBoundary.reload")).toBeDefined(); consoleErrorSpy.mockRestore(); }); diff --git a/apps/web/src/components/ui/ErrorBoundary.tsx b/apps/web/src/components/ui/ErrorBoundary.tsx index d5576dfc..a118eeac 100644 --- a/apps/web/src/components/ui/ErrorBoundary.tsx +++ b/apps/web/src/components/ui/ErrorBoundary.tsx @@ -1,6 +1,7 @@ import { Component, type ErrorInfo, type ReactNode } from "react"; +import { withTranslation, type WithTranslation } from "react-i18next"; -interface ErrorBoundaryProps { +interface ErrorBoundaryProps extends WithTranslation { children: ReactNode; } @@ -12,7 +13,7 @@ interface ErrorBoundaryState { // failures TanStack Query already surfaces via isError/error (handled inline // in VaultPanel). A boundary can't recover from a render error other than // remounting its subtree, so this deliberately only offers a reload. -export class ErrorBoundary extends Component< +class ErrorBoundaryBase extends Component< ErrorBoundaryProps, ErrorBoundaryState > { @@ -32,16 +33,15 @@ export class ErrorBoundary extends Component< render() { if (this.state.hasError) { + const { t } = this.props; return (
-

- Something went wrong. Please reload the page. -

+

{t("errorBoundary.title")}

); @@ -49,3 +49,5 @@ export class ErrorBoundary extends Component< return this.props.children; } } + +export const ErrorBoundary = withTranslation()(ErrorBoundaryBase);