Skip to content

fix(agent): handle vnstat 1.x JSON format to prevent frontend crash#169

Merged
s0up4200 merged 2 commits into
developfrom
fix/vnstat-v1-compat-163
Jan 24, 2026
Merged

fix(agent): handle vnstat 1.x JSON format to prevent frontend crash#169
s0up4200 merged 2 commits into
developfrom
fix/vnstat-v1-compat-163

Conversation

@s0up4200

@s0up4200 s0up4200 commented Jan 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds backend normalization of vnstat JSON v1 format (vnstat 1.18 and earlier) to v2 format in the agent's historical export handler
  • Renames plural keys (hours/days/months) to singular (hour/day/month)
  • Synthesizes missing time field for hour entries from the id field
  • Adds defensive null checks in the frontend parseMonitorUsagePeriods to prevent crashes if any period data is missing
  • Removes debug console.log statements from production code
  • Uses existing MonitorPeriod type instead of inline type literals

Test plan

  • Unit tests added for normalizeVnstatV1 covering: full normalization, missing day in date, no interfaces, empty traffic
  • Existing formatBytesPerSecond test converted to subtests
  • go test ./internal/agent/ passes
  • pnpm tsc --noEmit passes
  • Verify with an actual vnstat 1.18 agent that bandwidth data displays correctly

Fixes #163

Summary by CodeRabbit

  • New Features

    • Improved parsing and time-handling for monitor usage periods, with graceful empty-period summaries and more accurate week/month calculations.
    • Added normalization to accept older network traffic data formats.
  • Bug Fixes

    • Improved resilience when traffic data is missing or incomplete; avoids errors and preserves sensible summaries.
  • Tests

    • Added comprehensive tests for data-format normalization, edge cases, and byte-rate formatting.

✏️ Tip: You can customize this high-level summary in your review settings.

Normalize vnstat JSON v1 format (used by vnstat 1.18 and earlier) to v2
format in the agent's historical export handler. Key differences handled:
- "hours"/"days"/"months" (plural) renamed to "hour"/"day"/"month" (singular)
- "time" field added to hour entries derived from the "id" field
- "day" added to date objects when missing from hour entries

Also adds defensive null checks in the frontend parser to prevent crashes
if invalid data makes it through.

Fixes #163
@s0up4200

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jan 24, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jan 24, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds server-side normalization that converts vnstat JSON v1 (plural keys, missing hour time) into v2-like structure before timezone enrichment and frontend parsing; includes tests and frontend parser adjustments to handle missing traffic periods.

Changes

Cohort / File(s) Summary
Backend normalization
internal/agent/bandwidth.go
Adds normalizeVnstatV1(data map[string]any) and invokes it when jsonversion == "1". Converts plural traffic keys (hourshour, daysday, monthsmonth), synthesizes time fields for hour entries (deriving hour/minute from id), ensures a date.day when missing, and sets jsonversion to "2" before further processing.
Backend tests
internal/agent/bandwidth_test.go
New tests covering standard v1→v2 normalization, hour entries lacking day, no interfaces, empty traffic, and formatBytesPerSecond formatting across units.
Frontend parser
web/src/utils/monitorDataParser.ts
Refactors parsing to tolerate missing traffic periods: introduces EMPTY_SUMMARY, MonitorPeriod usage, resolveAgentTime, guarded access returning empty summaries when hour/day/month arrays are absent, and helper date utilities for week/month calculations.

Sequence Diagram(s)

sequenceDiagram
  participant Agent as Agent (vnStat JSON)
  participant Backend as Backend normalize
  participant Backend2 as Backend enrich
  participant Frontend as Frontend parser

  Agent->>Backend: send vnstat JSON (jsonversion "1" or "2")
  Backend->>Backend: if jsonversion == "1" → normalizeVnstatV1 (rename keys, synthesize time, set "2")
  Backend->>Backend2: add server_time / timezone info
  Backend2->>Frontend: return normalized + enriched JSON
  Frontend->>Frontend: parseMonitorUsagePeriods (guard missing periods, compute summaries)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through keys both old and new,
Turned "hours" to "hour" and forged timestamps true.
Tests snugly tucked, the frontend won't sigh—
Old vnstat whispers now speak clear and spry.
Hooray for compatibility, one small hop high! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.79% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately summarizes the main change: handling vnstat 1.x JSON format to prevent frontend crashes, which is the core objective of the PR.
Linked Issues check ✅ Passed The PR addresses all coding requirements from issue #163: normalizes vnstat v1 JSON to v2 format in backend [163], adds defensive null checks in frontend [163], and includes tests for normalization [163].
Out of Scope Changes check ✅ Passed All changes are in scope: backend normalization and tests for vnstat v1-to-v2 conversion directly address #163, frontend null checks prevent crashes, and console.log removal is minor cleanup supporting the fix.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@web/src/utils/monitorDataParser.ts`:
- Around line 21-45: The early-return in monitorDataParser (the branch that
currently returns getEmptyUsage() when !traffic.hour && !traffic.day &&
!traffic.month) discards traffic.total; change this so that when period data is
missing you still return an object that preserves the "All Time" total (use
traffic.total when present) while keeping other period entries as empty. Locate
the guard around traffic and modify it to build the final return shape (the
object with keys like "This Hour", "Last Hour", Today, "This week", "This
Month", and "All Time") so that "All Time" uses traffic.total (or converts it
into {download:0, upload:0, total: traffic.total} if needed) instead of dropping
it; keep calls to
getCurrentHour/getLastHour/getToday/getThisWeek/getCurrentMonth and
getEmptyUsage for missing periods and use
data.server_time/data.server_time_unix/ timezone logic unchanged.
🧹 Nitpick comments (1)
internal/agent/bandwidth.go (1)

170-227: Avoid time drift by reusing a single now.

time.Now() is called inside normalization and again for server_time. If this crosses midnight, hour entries may get a different day than server_time, which can skew frontend matching. Consider capturing now once and passing it into normalization for consistency and deterministic behavior.

♻️ Proposed refactor
-	// Normalize vnstat 1.x JSON format to 2.x format
-	// vnstat 1.x uses "hours"/"days"/"months" (plural) and lacks "time" fields
-	// vnstat 2.x uses "hour"/"day"/"month" (singular) with "time" fields
-	if jsonVer, ok := bandwidthData["jsonversion"].(string); ok && jsonVer == "1" {
-		normalizeVnstatV1(bandwidthData)
-	}
-
-	// Add server time information for timezone handling
-	now := time.Now()
+	// Capture time once for normalization + server_time
+	now := time.Now()
+
+	// Normalize vnstat 1.x JSON format to 2.x format
+	// vnstat 1.x uses "hours"/"days"/"months" (plural) and lacks "time" fields
+	// vnstat 2.x uses "hour"/"day"/"month" (singular) with "time" fields
+	if jsonVer, ok := bandwidthData["jsonversion"].(string); ok && jsonVer == "1" {
+		normalizeVnstatV1(bandwidthData, now)
+	}
-func normalizeVnstatV1(data map[string]any) {
+func normalizeVnstatV1(data map[string]any, now time.Time) {
 ...
-						dateMap["day"] = float64(time.Now().Day())
+						dateMap["day"] = float64(now.Day())

Comment thread web/src/utils/monitorDataParser.ts Outdated
…itorDataParser

Prevent crash when traffic.total is undefined by adding a null guard
for the "All Time" entry. Fix getThisWeek to use UTC-safe date methods
consistently when isUTC is true, ensuring week boundaries are computed
correctly regardless of timezone.
@s0up4200 s0up4200 merged commit 2e0e7d8 into develop Jan 24, 2026
10 checks passed
@s0up4200 s0up4200 deleted the fix/vnstat-v1-compat-163 branch January 24, 2026 10:14
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.

Frontend crashes when displaying agents running vnstat 1.18

1 participant