fix(views): guard server info before dereferencing in templates - #933
fix(views): guard server info before dereferencing in templates#933TimeToBuildBob wants to merge 1 commit into
Conversation
useServerStore starts with `info: null` and is only populated from App.vue's
`mounted` hook, which runs after the first child render. Two templates
dereferenced `info` unguarded, so a cold load of either view threw:
TypeError: null is not an object (evaluating 't.info.version')
surfacing as a red error banner over an otherwise working install. When the
server is unreachable the crash is permanent, not transient: getInfo() catches
the connection error and leaves `info` null forever.
- Home.vue: `!info.version.includes('rust')` -> guard `info` first
- Buckets.vue: `serverStore.info.hostname == device.hostname` -> same
Footer.vue was already safe via an ancestor `v-if="info"`.
Adds a pug-indentation-aware regression test that walks the template tree and
rejects any `info.*` dereference not covered by a guard on itself or an
ancestor, so an ancestor `v-if="info"` (Footer's pattern) still passes while a
sibling after a closed guard block does not.
Reported against the ActivityWatch Research Edition build (v0.14.0b3-research),
where a participant read the banner as "ActivityWatch isn't working".
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #933 +/- ##
=======================================
Coverage 42.53% 42.53%
=======================================
Files 44 44
Lines 2417 2417
Branches 519 519
=======================================
Hits 1028 1028
Misses 1368 1368
Partials 21 21 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Greptile SummaryAdds null guards around server-info dereferences so Home and Buckets render safely before server metadata loads or when the server remains unavailable.
Confidence Score: 5/5The PR appears safe to merge, with both affected template dereferences guarded and focused regression coverage added. The new short-circuit conditions prevent null server metadata from reaching either property access without changing behavior once metadata is available. Important Files Changed
Reviews (1): Last reviewed commit: "fix(views): guard server info before der..." | Re-trigger Greptile |
|
CI-green and mergeable (Greptile 5/5) — waiting only on a maintainer click. This PR is ready to merge, but the bot has pull-only access to this repo and can't self-merge — surfacing it here so it isn't lost. The monitoring loop will stop re-flagging it now that this note is posted. |
Problem
useServerStorestarts withinfo: nulland is only populated fromApp.vue'smountedhook — which runs after the first child render. Two templatesdereferenced
infounguarded, so a cold load of either view throws:It renders as a red error banner over an otherwise perfectly working install.
Worse, when the server is unreachable the crash is permanent, not a
first-paint race:
getInfo()catches the connection error and leavesinfonull forever, so the banner never clears.
Sites
src/views/Home.vue:74!info.version.includes('rust')src/views/Buckets.vue:20serverStore.info.hostname == device.hostnamesrc/components/Footer.vue:12,15info.hostname/info.versionv-if="info"src/stores/buckets.ts:44,187serverStore.info && ...Regression test
test/unit/serverInfoGuard.test.jswalks the pug template tree by indentationand rejects any
info.*dereference not covered by a guard on itself or anancestor. The indentation-awareness matters: a naive per-line check would
false-positive on Footer.vue, whose guard sits on the wrapping
span. Coveredboth ways — an ancestor guard passes, a sibling after a closed guard block
does not.
Verified against the pre-fix files from
master: the detector flags bothoffending lines and reports Footer clean, then reports all three clean after the
fix.
Verification
npx jest --selectProjects jsdom— 14 suites, 69 tests passmake lintclean on the changed filesOrigin
Found while triaging a participant's test report on the ActivityWatch Research
Edition build (
v0.14.0b3-research). The install was working correctly and theprivacy filter was doing its job, but the banner made it look broken.