Problem
When any dashboard API call fails, the affected panel stays stuck on its loading skeleton forever. useApiQuery has retry: false, so the first failure is terminal — users see a shimmer that never resolves and have no way to recover without a page reload.
Affected panels:
StatsPanel
MinerRatesTable
OrderbookDepth
EventFeed
SwapTracker
SwapDetailPage
Proposed change
Add a small QueryError component with a retry button, and show it in each consumer when the query has errored and has no data to fall back on.
// src/components/QueryError.tsx — icon + message + retry button, styled to match panels
<QueryError onRetry={() => refetch()} />
Each consumer gets one early return:
const { data, isLoading, isError, refetch } = useStats();
if (isError && !data) return <QueryError onRetry={() => refetch()} />;
Behavior
- First-load failure →
QueryError replaces the skeleton. Retry re-runs the query.
- Refetch failure while data exists → silent; keep showing stale data (via
keepPreviousData). Avoids flashing errors over working UI during transient blips.
- SwapDetailPage →
QueryError rendered inline inside PageWrapper so header/layout stay.
Out of scope
- Global retry/backoff in
useApiQuery (no change to retry: false).
- ErrorBoundary for render-time errors.
- Telemetry / error reporting hook.
- SSE reconnect timer fix.
Files touched
src/components/QueryError.tsx (new)
src/components/index.ts
src/components/dashboard/StatsPanel.tsx
src/components/dashboard/MinerRatesTable.tsx
src/components/dashboard/OrderbookDepth.tsx
src/components/dashboard/EventFeed.tsx
src/components/dashboard/SwapTracker.tsx
src/pages/SwapDetailPage.tsx
Problem
When any dashboard API call fails, the affected panel stays stuck on its loading skeleton forever.
useApiQueryhasretry: false, so the first failure is terminal — users see a shimmer that never resolves and have no way to recover without a page reload.Affected panels:
StatsPanelMinerRatesTableOrderbookDepthEventFeedSwapTrackerSwapDetailPageProposed change
Add a small
QueryErrorcomponent with a retry button, and show it in each consumer when the query has errored and has no data to fall back on.Each consumer gets one early return:
Behavior
QueryErrorreplaces the skeleton. Retry re-runs the query.keepPreviousData). Avoids flashing errors over working UI during transient blips.QueryErrorrendered inline insidePageWrapperso header/layout stay.Out of scope
useApiQuery(no change toretry: false).Files touched
src/components/QueryError.tsx(new)src/components/index.tssrc/components/dashboard/StatsPanel.tsxsrc/components/dashboard/MinerRatesTable.tsxsrc/components/dashboard/OrderbookDepth.tsxsrc/components/dashboard/EventFeed.tsxsrc/components/dashboard/SwapTracker.tsxsrc/pages/SwapDetailPage.tsx