Schema/diagram images have no broken-image fallback — 404 renders broken glyph with no UX feedback #90
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
When an exploded-view schema/diagram image (parça şeması) fails to load (404 / missing from MinIO), the UI gives the user no feedback at all:
HotspotOverlaystill draws clickable hotspots over the (empty) image area.onErrorhandler, fallback image, "Şema bulunamadı" message, retry, or skeleton anywhere.Users keep clicking categories and rage-click waiting for an image that will never appear. This is distinct from #73 (category-click loading spinner) and #76 (mobile schema-page layout) — neither touched image-load error handling.
Evidence (file:line —
apps/web)apps/web/src/components/schema/schema-viewer.tsx:158-165— main viewer image:onError, noonLoad, no broken-image fallback. TheHotspotOverlaybelow still renders when width/height > 0, so hotspots float over a broken image.apps/web/src/components/categories/category-tree.tsx:292— hover-preview thumbnail inSchemaIcon:grep -rn "onError" apps/web/srcon<img>returns nothing — there is no broken-image handling anywhere in the frontend.Why the URLs 404 (root cause of the missing object)
schemas/psa-${categoryId}.png:apps/api/src/categories/categories.service.ts:1333-1344(key + insert intoschemaPics.imageUrl)apps/api/src/storage/storage.service.ts:81-83—getPublicUrl(key) => ${publicUrl}/${key}sase-schemas—apps/api/src/config/configuration.ts:21/sase-schemas/schemas/psa-*.pngpaths. Because the URL is stored in the DB, if the MinIO object is missing/deleted the URL becomes a permanent 404 — and the frontend has no way to know, so it shows a broken image indefinitely.Reproduction
schemaPics[0].urlpoints to a MinIO object that 404s (or temporarily make the object unreachable, e.g. rename it in the bucket).Proposed fix
Frontend (primary):
schema-viewer.tsx, addonErrorto the<img>to flip a localimageFailedstate. When true:srcwith a cache-bust query param), andHotspotOverlayso hotspots don't float over emptiness.SkeletonuntilonLoadfires (loading state).category-tree.tsxSchemaIcon, addonErrorthat falls back to the default<Icon />(treat a failed image the same as a null URL — that path is already handled).Backend (optional follow-up):
schemaPics.imageUrlrows whose MinIO objects no longer exist, so the frontend's already-handled null-URL path kicks in instead of a broken<img>.Related latent risk — schema-image prefetch & rate-limit (from K4 analysis, fold in here)
The schema-image prefetch loop amplifies requests and shares this area:
category-grid.tsx:73-127,category-tree.tsx:111-155,category-columns.tsx:153-198— for each leaf withschemaImageUrl == null(categories.service.ts:1689) it calls/vehicles/:id/categories/:leafIdin batches of 2, plus a/categories/:parentId/childrenrefetch after every batch (~1.5N requests/level).app.module.ts:65-70); exceeding it returns 429 (GEN_004,http-exception.filter.ts:88).@SkipThrottle(or a higher per-route limit) to the read-only categories/vehicles GET routes; (b) drop the per-batch parent/childrenre-fetch and/or widen the prefetch batch interval.Acceptance criteria
schemaPics.imageUrlrows.Verification checklist (confirm "fixed")
srcat a 404 URL → confirm broken glyph + floating hotspots (failing baseline)./sase-schemas/schemas/psa-*.pngno longer correlate with rage-clicks.cmplpibau(occ 19, active) andcmpwew68do not recur (panel auto-flagsregressed).GEN_004.Notes / data caveat
cmplpibau001014ozj7bg39a3: 19 occurrences, status=new, last seen 2026-06-03 (active).cmpwew68u001v14fzhr60id7h: 1 occ, P2.posthog_eventstable for these sessions does not contain those rows, so 404 frequency isn't independently verifiable from events — but the absence of any UX handling for broken images is confirmed in code.Filed from Süper Panel insight triage (2026-06-03). Covers insight(s): cmplpibau0 · cmpwew68u0. Canonical:
cmplpibau001014ozj7bg39a3.🤖 Fusion task opened:
FN-436Triage queue: https://fusion.semih.ai/tasks/FN-436
This comment was posted automatically by the
fusion-plugin-gitea-issuesbridge. A Fusion agent will update this issue when the task moves to in-progress, in-review, or done.