Pagină albă când API-ul nu răspunde
Dacă backend-ul cade sau doar se repornește, vizitatorul nu vede un magazin gol și nici un mesaj de eroare: vede o pagină complet albă, fără antet, fără subsol, fără buton de reîncercare. Nu are cum să înțeleagă că e o defecțiune temporară — arată ca un site stricat, iar Googlebot vede același gol. Cauza e o eroare re-aruncată dintr-o promisiune, care nu ajunge niciodată la React, plus lipsa oricărei plase de siguranță la randare.
Ce am găsit
Orice eroare care nu e 404 lasă pagina blocată pe ecranul gol de încărcare
frontend/src/pages/CollectionRoute.tsx:95-102:
.catch((cause: unknown) => {
if (cancelled) return;
if (cause instanceof ApiError && cause.status === 404) {
setNotFound(true);
return;
}
throw cause;
});
Backend căzut, 502 sau eroare de rețea intră toate pe ramura throw cause, dintr-un .catch de promisiune — deci excepția nu ajunge la React. collection rămâne null, iar CollectionRoute.tsx:110 returnează la nesfârșit PageFallback:
if (!collection) return <PageFallback />;
PageFallback (CollectionRoute.tsx:37-39) e un div gol:
function PageFallback() {
return <div className="min-h-screen" aria-hidden="true" />;
}
Reprodus pe producție, în browser real, viewport 375px: cu window.fetch înlocuit ca să respingă orice cerere către api.hyperice.md, navigarea în aplicație la /collections/venom dă document.body.innerText egal cu șirul gol, captură complet albă, document.getElementById('root').innerHTML egal cu <div class="min-h-screen" aria-hidden="true"></div> și, în consolă, Uncaught (in promise) TypeError: Failed to fetch.
Nu există nicio plasă de siguranță la randare
$ grep -rnE "ErrorBoundary|componentDidCatch|getDerivedStateFromError|errorElement" --include='*.tsx' --include='*.ts' frontend/src/ | wc -l
0
Aceeași aplicație tratează deja elegant eșecul de rețea în altă parte: frontend/src/lib/catalog.ts:251 și :297 prind eroarea și lasă meniurile nefiltrate, în loc să arunce mai departe. Ruta de colecție nu face la fel.
De făcut
-
În CollectionRoute.tsx, înlocuieștethrow causecu setarea unei stări de eroare și randarea unui ecran „nu am putut încărca, încearcă din nou" care păstrează antetul și subsolul. -
Adaugă un ErrorBoundaryîn jurul rutelor înApp.tsx, ca orice excepție de randare să dea un ecran de eroare cu antet și subsol, nu o pagină albă.
Criteriu de acceptare
Cu API-ul indisponibil (cereri către api.hyperice.md respinse), /collections/venom și o pagină de produs afișează antetul, subsolul și un mesaj vizibil de eroare; document.body.innerText nu mai e gol, iar consola nu mai are respingeri de promisiune netratate.