fix: search empty state never renders due to stale fetch race condition (#144)#146
Conversation
…on (#144) Co-authored-by: Ona <no-reply@ona.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
✅ UI verification passed — design spec compliance confirmed. Static analysis: All changes are behavioral (AbortController for fetch cancellation, signal.aborted guards). No color tokens, typography, spacing, component usage, or accessibility attributes were modified. No design spec violations. Visual verification (Playwright screenshots on production):
The fix correctly resolves the stale fetch race condition — the empty state now appears instead of infinite skeletons. |
|
✅ Post-merge verification passed. E2E suite: 39/42 passed. 3 pre-existing flaky failures in Ad-hoc smoke tests — all passed:
Skipped: |
Closes #144
What
The search empty state ("No pages match your search") never renders when searching for a nonsense string. Instead, skeleton loading placeholders show indefinitely. This bug persisted across multiple fix attempts (#126, #136) because the root cause — stale fetch responses corrupting component state — was never addressed.
How
Added
AbortControllerto cancel in-flight fetch requests when the search query or workspace changes. Without cancellation, a stale fetch response could setloading = falseat the wrong time (e.g., between a new debounce cycle settingloading = trueand the new fetch completing), leaving the component in an inconsistent state where neither skeletons nor the empty state rendered.Key changes:
AbortControllerand passes its signal tofetch()awaitare guarded withsignal.abortedcheckssearched = falsewhen starting a new search cycle, preventing stalesearched = truefrom a previous cycleTesting
pnpm test)pnpm test:e2e), including the previously failingsearch with no matches shows empty statepnpm lint && pnpm typecheckpass