Skip to content

Fix new high-severity SonarCloud issues - #86

Merged
LarsLaskowski merged 2 commits into
mainfrom
claude/sonar-high-severity-issues-4snxak
Aug 16, 2026
Merged

Fix new high-severity SonarCloud issues#86
LarsLaskowski merged 2 commits into
mainfrom
claude/sonar-high-severity-issues-4snxak

Conversation

@LarsLaskowski

@LarsLaskowski LarsLaskowski commented Aug 16, 2026

Copy link
Copy Markdown
Owner

📖 Description

Fixes the 8 currently-open SonarCloud issues at HIGH severity (MAINTAINABILITY impact) on LarsLaskowski_PiMonitor. Lower-severity issues (MEDIUM/LOW) are intentionally left for a follow-up, as requested.

  • go:S3776 — Cognitive Complexity (internal/alert/alert.go:232, internal/collector/persist.go:208, internal/collector/disk.go:185): Engine.evalMetric, decodeHistory, and DiskCollector.Collect each exceeded the 15-point limit (20–21). Extracted the per-mountpoint statfs logic (collectDisk, dedupeMounts, markBad), the per-series binary decode logic (decodeSeries, decodeHistoryPoints), and the debounce state machine (updateThresholdState, nextLevel) into focused helper functions. Pure refactor — behavior is unchanged.
  • javascript:S7761 — Prefer .dataset over setAttribute/removeAttribute (internal/web/assets/theme-init.js:12, internal/web/assets/app.js:80,82): switched the data-theme toggle to element.dataset.theme = … / delete element.dataset.theme.
  • javascript:S3504 — Prefer let/const over var (internal/web/assets/theme-init.js:10): var storedconst stored.
  • Web:S7927 — Accessible name should include the visible label (internal/web/assets/index.html:87): the Memory & Swap card's aria-label ("Open memory usage detail") didn't contain its visible label text, unlike the other three metric cards. Changed to "Open Memory & Swap detail".

🎫 Issues

N/A (SonarCloud housekeeping, no linked GitHub issue).

👩‍💻 Reviewer Notes

All changes are behavior-preserving refactors or trivial JS/HTML style fixes — no functional/API change. Worth a close read of the extracted disk.go/persist.go/alert.go helpers to confirm the control flow still matches the original exactly (I cross-checked each branch against the existing tests, which already exercise the affected paths: timeout/cooldown, zero-size mount, dedup, truncated/corrupt history, debounce escalation/flapping).

📑 Test Plan

  • go build ./..., go vet ./..., go test ./... -race -cover — all pass, no test changes needed since existing tests already cover every branch touched by the refactor.
  • golangci-lint run — 0 issues.
  • No test suite exists for the vanilla JS assets; the .dataset/const changes are behaviorally identical (verified by reading style.css's [data-theme] selectors, which are unaffected by the attribute being set via setAttribute vs. dataset).

✅ Checklist

General

  • I have added/updated tests for my changes (go test ./... -race -cover passes locally). (No new tests needed — behavior-preserving refactor, already covered.)
  • go vet ./... and golangci-lint run are clean.
  • I have tested my changes.
  • I have read the CONTRIBUTING documentation and followed the project's code style guidelines.
  • I have updated ARCHITECTURE.md if this changes a documented design decision. (N/A — no design decision changed.)

⏭ Next Steps

The remaining 37 open SonarCloud issues (17 MAJOR/MEDIUM, 20 MINOR/LOW as of this PR) were left untouched per the request to focus on high severity first.

claude added 2 commits August 16, 2026 14:14
- Reduce cognitive complexity of DiskCollector.Collect, decodeHistory,
  and Engine.evalMetric below the 15 threshold by extracting the
  per-mountpoint, per-series, and state-transition logic into focused
  helper functions (go:S3776). Behavior is unchanged and covered by
  existing tests.
- Prefer element.dataset over setAttribute/removeAttribute for the
  data-theme toggle (javascript:S7761).
- Replace var with const in theme-init.js (javascript:S3504).
- Make the Memory & Swap card's accessible name include its visible
  label text, matching the other metric cards (Web:S7927).
sonar.projectKey pointed at networlddev_PiMonitor, which does not exist
on SonarCloud (confirmed 404 via the components API). The real project
lives under the same networlddev organization as LarsLaskowski_PiMonitor.
With the wrong key, CI analysis was landing on a non-existent/ghost
project instead of the one actually tracked on the dashboard.

LarsLaskowski commented Aug 16, 2026

Copy link
Copy Markdown
Owner Author

Added a fix for the SonarCloud project key mismatch you flagged: sonar-project.properties had sonar.projectKey=networlddev_PiMonitor, which returns 404 on the SonarCloud API — that key doesn't exist. The real, actively-analyzed project (same networlddev organization, public, last analysis today) is LarsLaskowski_PiMonitor. Fixed in c003539.

@sonarqubecloud

Copy link
Copy Markdown

Repository owner deleted a comment from sonarqubecloud Bot Aug 16, 2026
@LarsLaskowski
LarsLaskowski merged commit 364b1b1 into main Aug 16, 2026
5 checks passed
@LarsLaskowski
LarsLaskowski deleted the claude/sonar-high-severity-issues-4snxak branch August 16, 2026 14:22

Copy link
Copy Markdown
Owner Author

Added the remaining 25 open MEDIUM/LOW-severity SonarCloud issues in commit d378425 (33 total minus the 2 accessibility rules that only fully resolve via the same HTML restructure, counted together below):

  • godre:S8193 (2×, Go tests): dropped unnecessary variable declarations in if conditions.
  • javascript:S2486 (3×): explained the previously-silent catch blocks around localStorage access (private browsing / disabled storage).
  • javascript:S6582 / S7755 (8×): optional chaining instead of manual && guards, .at(-1) instead of arr[arr.length - 1].
  • javascript:S3358 (1×): extracted a nested ternary in gauge.js into a small helper.
  • css:S1874 (4×): word-break: break-wordoverflow-wrap: break-word (the deprecated keyword's modern replacement).
  • Web:S6842 / Web:S6819 / MouseEventWithoutKeyboardEquivalentCheck (12× across the 4 metric card headers and the 3 modals): replaced <h2 role="button" tabindex="0"> with a real <button> (keyboard activation now free, could delete the hand-rolled keydown handler), and replaced the 3 role="dialog" backdrop divs with native <dialog> elements (native focus trap + Escape handling let a fair amount of hand-rolled modal JS go away; the API key prompt's "not dismissible" behavior is preserved via preventDefault() on the dialog's cancel event).
  • Web:S6819 (1×): the range-picker's role="group" div became a <fieldset> with a screen-reader-only <legend>.

This is the most behaviorally-sensitive part of the two PRs, so I ran it in a real browser (Playwright/Chromium) rather than relying on the Go test suite alone (which doesn't cover the JS/HTML): card header buttons open the detail modal via click and Enter, all three dialogs open/close via trigger, Escape, and backdrop click (except the API key prompt, which correctly ignores both), focus returns to the triggering element on close, native focus trapping keeps Tab inside the open dialog, and the whole card — not just the header button — is still clickable. No visual regressions in light or dark theme.

One real bug came out of that verification and is already fixed in the same commit: dialog.modal { display: flex; } unconditionally overrode the browser's default dialog:not([open]) { display: none }, which would have left every dialog permanently visible (in-flow, at the bottom of the page) even when closed. Scoped to dialog.modal[open].

go build, go vet, go test ./... -race -cover, and golangci-lint run are all clean.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants