/geography crashes on anonymous load — uncaught exception, component body never mounts #308

Closed
opened 2026-07-01 20:27:14 +00:00 by spikerj · 2 comments
Owner

Found by the E2E anonymous walk (epic #307, harness PR spikersoft-angular#90).

Symptom

Navigating to /geography as an anonymous visitor throws an uncaught client-side exception ([pageerror] k in the minified prod bundle). The Playwright page snapshot shows only the header/menu-bar rendered — the GeographyExplorerComponent body never mounts.

Repro

  1. pnpm build && pnpm e2e --grep "loads geography" in spikersoft-angular (branch test/issue-307-e2e-full-coverage or after PR #90 merges).
  2. Or manually: open /geography in a browser as an anonymous user with dev tools open — observe the uncaught exception.

Notes

  • Route is declared public (canActivate: []) in projects/spikersoft/src/routes.ts, so anonymous load must work.
  • Needs a source-mapped stack to identify the throwing code; likely an init-time dependency that assumes an authenticated context or missing data.

Part of epic #307.

Found by the E2E anonymous walk (epic #307, harness PR spikersoft-angular#90). ## Symptom Navigating to `/geography` as an anonymous visitor throws an uncaught client-side exception (`[pageerror] k` in the minified prod bundle). The Playwright page snapshot shows only the header/menu-bar rendered — the `GeographyExplorerComponent` body never mounts. ## Repro 1. `pnpm build && pnpm e2e --grep "loads geography"` in `spikersoft-angular` (branch `test/issue-307-e2e-full-coverage` or after PR #90 merges). 2. Or manually: open `/geography` in a browser as an anonymous user with dev tools open — observe the uncaught exception. ## Notes - Route is declared public (`canActivate: []`) in `projects/spikersoft/src/routes.ts`, so anonymous load must work. - Needs a source-mapped stack to identify the throwing code; likely an init-time dependency that assumes an authenticated context or missing data. Part of epic #307.
spikerj added the bug label 2026-07-01 20:27:14 +00:00
Author
Owner

Root cause identified and fix pushed to spikersoft-angular PR #90 (commit ee58881 on test/issue-307-e2e-full-coverage).

Root cause — two unhandled-error paths in GeographyExplorerComponent, both triggered whenever the API is unreachable (the E2E run surfaced it via CORS: the local Playwright origin http://127.0.0.1:4200 is not in the backend Origins allowlist, so every API call failed):

  1. ngOnInit fire-and-forgets loadInitialData(); its try/finally had no catch, so a failed getCountries() escaped as an unhandled promise rejection ([pageerror] k).
  2. loadInterests() subscribed to interestsService.getAll() with only a next handler — RxJS rethrows a failed request from a handlerless subscription.

Fix: catch in loadInitialData() (snackbar geoExplorer.runtime.failedInitialLoad, en+es keys added, page degrades to an empty explorer) and an error callback in loadInterests() (empty interest list). Anonymous walk now passes /geography.

Will close when PR #90 merges. Note for the epic: adding http://127.0.0.1:4200 to the API Origins allowlist would let local E2E runs exercise the real API instead of failing CORS.

Root cause identified and fix pushed to spikersoft-angular PR #90 (commit `ee58881` on `test/issue-307-e2e-full-coverage`). **Root cause** — two unhandled-error paths in `GeographyExplorerComponent`, both triggered whenever the API is unreachable (the E2E run surfaced it via CORS: the local Playwright origin `http://127.0.0.1:4200` is not in the backend `Origins` allowlist, so every API call failed): 1. `ngOnInit` fire-and-forgets `loadInitialData()`; its `try/finally` had **no catch**, so a failed `getCountries()` escaped as an unhandled promise rejection (`[pageerror] k`). 2. `loadInterests()` subscribed to `interestsService.getAll()` with only a `next` handler — RxJS rethrows a failed request from a handlerless subscription. **Fix**: catch in `loadInitialData()` (snackbar `geoExplorer.runtime.failedInitialLoad`, en+es keys added, page degrades to an empty explorer) and an error callback in `loadInterests()` (empty interest list). Anonymous walk now passes `/geography`. Will close when PR #90 merges. Note for the epic: adding `http://127.0.0.1:4200` to the API `Origins` allowlist would let local E2E runs exercise the real API instead of failing CORS.
Author
Owner

Resolved in spikersoft-angular PR #90 (merged to master). loadInitialData() now catches API failures (snackbar + graceful degrade) and loadInterests() subscribes with an error handler. Anonymous walk passes /geography. Closing.

Resolved in spikersoft-angular PR #90 (merged to `master`). `loadInitialData()` now catches API failures (snackbar + graceful degrade) and `loadInterests()` subscribes with an error handler. Anonymous walk passes `/geography`. Closing.
Sign in to join this conversation.