diff --git a/apps/minifront/src/components/extension-unavailable.tsx b/apps/minifront/src/components/extension-unavailable.tsx new file mode 100644 index 0000000000..fed5543344 --- /dev/null +++ b/apps/minifront/src/components/extension-unavailable.tsx @@ -0,0 +1,29 @@ +import { SplashPage } from '@penumbra-zone/ui'; +import { HeadTag } from './metadata/head-tag'; + +const NODE_STATUS_PAGE_URL = + window.location.hostname === 'localhost' ? 'http://localhost:5174' : '/'; + +export const ExtensionUnavailable = () => { + return ( + <> + + + +

We can't currently connect to the Penumbra extension.

+

+ This page may have been left open for too long, causing a timeout. Please reload this page + and see if that fixes the issue. +

+

+ If it doesn't, the RPC node that you're connected to could be down. Check{' '} + + the node's status page + {' '} + and, if it is down, consider switching to a different RPC URL in the Penumbra + extension's settings. +

+
+ + ); +}; diff --git a/apps/minifront/src/components/not-found.tsx b/apps/minifront/src/components/not-found.tsx new file mode 100644 index 0000000000..e0e7e88de4 --- /dev/null +++ b/apps/minifront/src/components/not-found.tsx @@ -0,0 +1,5 @@ +import { SplashPage } from '@penumbra-zone/ui'; + +export const NotFound = () => { + return That page could not be found. ; +}; diff --git a/apps/minifront/src/components/shared/error-boundary.tsx b/apps/minifront/src/components/shared/error-boundary.tsx index 06ab2a2619..b1f77a5ada 100644 --- a/apps/minifront/src/components/shared/error-boundary.tsx +++ b/apps/minifront/src/components/shared/error-boundary.tsx @@ -1,17 +1,25 @@ -import { useRouteError } from 'react-router-dom'; +import { isRouteErrorResponse, useRouteError } from 'react-router-dom'; import { PraxNotConnectedError } from '@penumbra-zone/client'; import { ExtensionNotConnected } from '../extension-not-connected'; +import { NotFound } from '../not-found'; +import { ExtensionUnavailable } from '../extension-unavailable'; +import { Code, ConnectError } from '@connectrpc/connect'; +import { SplashPage } from '@penumbra-zone/ui'; export const ErrorBoundary = () => { const error = useRouteError(); + if (error instanceof ConnectError && error.code === Code.Unavailable) { + return ; + } if (error instanceof PraxNotConnectedError) return ; + if (isRouteErrorResponse(error) && error.status === 404) return ; - console.error(error); + console.error('ErrorBoundary caught error:', error); return ( -
-

{String(error)}

-
+ + {String(error)} + ); }; diff --git a/apps/minifront/src/fetchers/chain-id.ts b/apps/minifront/src/fetchers/chain-id.ts index bff6aca319..0036a8888d 100644 --- a/apps/minifront/src/fetchers/chain-id.ts +++ b/apps/minifront/src/fetchers/chain-id.ts @@ -1,8 +1,6 @@ import { viewClient } from '../clients'; -export const getChainId = async (): Promise => { +export const getChainId = async (): Promise => { const { parameters } = await viewClient.appParameters({}); - if (!parameters?.chainId) throw new Error('No chainId in response'); - - return parameters.chainId; + return parameters?.chainId; }; diff --git a/apps/node-status/src/components/error-boundary.tsx b/apps/node-status/src/components/error-boundary.tsx index 2927484905..30e2129491 100644 --- a/apps/node-status/src/components/error-boundary.tsx +++ b/apps/node-status/src/components/error-boundary.tsx @@ -1,13 +1,14 @@ +import { SplashPage } from '@penumbra-zone/ui'; import { useRouteError } from 'react-router-dom'; export const ErrorBoundary = () => { const error = useRouteError(); - console.error(error); + console.error('ErrorBoundary caught error:', error); return ( -
-

{String(error)}

-
+ + {String(error)} + ); };