fix(ux): recoverable route error screen + smoke-test shop/spot routes
- The per-route 'slammed' screen only offered 'Go back', so a stale-chunk failure after a deploy trapped the user. Add a primary 'Reload' that clears the lazyWithRetry session flag and does a fresh reload. - Smoke test now boots /shop/:pubkey/:identifier, /spot/…, /event/…, /crew/… so a broken detail route can't ship again. - Investigation note: no reproducible slam across 11 live shops; the report matched a transient chunk miss from two rapid deploys.
This commit is contained in:
parent
ad75120a43
commit
391eeb9bf9
2 changed files with 28 additions and 7 deletions
|
|
@ -148,6 +148,10 @@ const ROUTES = [
|
||||||
'/card',
|
'/card',
|
||||||
'/card/npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx',
|
'/card/npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx',
|
||||||
'/verify/notarealnaddr',
|
'/verify/notarealnaddr',
|
||||||
|
'/shop/abc/def',
|
||||||
|
'/spot/abc/def',
|
||||||
|
'/event/abc/def',
|
||||||
|
'/crew/abc/def',
|
||||||
'/messages/group/abc123',
|
'/messages/group/abc123',
|
||||||
];
|
];
|
||||||
const problems = [];
|
const problems = [];
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,15 @@ import { ErrorBoundary } from '@/components/ErrorBoundary';
|
||||||
export function RouteErrorBoundary({ children }: { children: React.ReactNode }) {
|
export function RouteErrorBoundary({ children }: { children: React.ReactNode }) {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
|
// After a deploy an already-open tab can hold a stale module graph, so a lazy
|
||||||
|
// route import 404s. `lazyWithRetry` reloads once; if it still fails the
|
||||||
|
// boundary is shown — so give the user a real way out: clear the "already
|
||||||
|
// reloaded" flag and do a fresh reload (fetching the new index + chunks).
|
||||||
|
const hardReload = () => {
|
||||||
|
try { sessionStorage.removeItem('skatespots:chunk-reload'); } catch { /* ignore */ }
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary
|
<ErrorBoundary
|
||||||
key={location.pathname}
|
key={location.pathname}
|
||||||
|
|
@ -31,15 +40,23 @@ export function RouteErrorBoundary({ children }: { children: React.ReactNode })
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-sm text-gray-400">
|
<p className="text-sm text-gray-400">
|
||||||
Something on this screen tripped up. Your account and data are safe.
|
Something on this screen tripped up. Your account and data are safe.
|
||||||
Head back and try again.
|
Usually a quick reload sorts it out.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<div className="flex flex-col sm:flex-row gap-2">
|
||||||
onClick={() => window.history.back()}
|
<button
|
||||||
className="w-full px-4 py-3 rounded-full font-black uppercase bg-[#ff0040] text-white hover:bg-[#ff0040]/90 transition-colors"
|
onClick={hardReload}
|
||||||
>
|
className="flex-1 px-4 py-3 rounded-full font-black uppercase bg-[#ff0040] text-white hover:bg-[#ff0040]/90 transition-colors"
|
||||||
Go back
|
>
|
||||||
</button>
|
Reload
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => window.history.back()}
|
||||||
|
className="flex-1 px-4 py-3 rounded-full font-black uppercase bg-white/5 text-gray-300 border border-white/10 hover:bg-white/10 transition-colors"
|
||||||
|
>
|
||||||
|
Go back
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue