Combines two related findings from a codebase audit (B1, UX1) — same root cause, same fix.
Problem
B1: The `catch` block in `fetch3DTrajectory` (`src/utils/fetch3DTrajectory.ts` lines 27–30) only calls `console.log(error)` and never reports failure to the caller. If the S3 fetch fails (network error, file removed, etc.), `trajectoryStatus` stays `LOADING` indefinitely.
UX1: `trajectoryStatus` has `LOADING` and `ERROR` states (`src/types/index.ts`) but neither ever triggers any UI (`src/App.tsx`, `src/components/Viewer.tsx`). The viewer just stays blank — no spinner while loading, no error message on failure. Students on bonus content pages have no indication anything is happening, and a failed fetch shows nothing at all.
Severity: High
Fix
- Propagate fetch success/failure out of `fetch3DTrajectory` instead of swallowing it
- Set `trajectoryStatus` to `ERROR` on failure instead of always `LOADED`
- Show a loading spinner while `trajectoryStatus === LOADING` and an error message with a retry option when `trajectoryStatus === ERROR`
🤖 Filed via Claude Code from a codebase audit.
Combines two related findings from a codebase audit (B1, UX1) — same root cause, same fix.
Problem
B1: The `catch` block in `fetch3DTrajectory` (`src/utils/fetch3DTrajectory.ts` lines 27–30) only calls `console.log(error)` and never reports failure to the caller. If the S3 fetch fails (network error, file removed, etc.), `trajectoryStatus` stays `LOADING` indefinitely.
UX1: `trajectoryStatus` has `LOADING` and `ERROR` states (`src/types/index.ts`) but neither ever triggers any UI (`src/App.tsx`, `src/components/Viewer.tsx`). The viewer just stays blank — no spinner while loading, no error message on failure. Students on bonus content pages have no indication anything is happening, and a failed fetch shows nothing at all.
Severity: High
Fix
🤖 Filed via Claude Code from a codebase audit.