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)}
+
);
};