glanceapp/glance · error

fetching stats: %v

Error message

fetching stats: %v

What it means

Returned by the Pi-hole v6 stats fetcher after all parallel requests complete: the primary stats request (statsErr) failed, which is fatal — unlike the graph (series) and top-domains requests, whose failures only downgrade to errPartialContent. The wrapped error comes from decodeJsonFromRequest on the main stats endpoint.

Source

Thrown at internal/glance/widget-dns-stats.go:532

	var topDomainsResponse topDomainsResponseJson
	var topDomainsErr error

	if includeTopDomains {
		topDomainsRequest, _ := http.NewRequestWithContext(ctx, "GET", instanceURL+"/api/stats/top_domains?blocked=true", nil)
		topDomainsRequest.Header.Set("x-ftl-sid", sessionID)

		wg.Add(1)
		go func() {
			defer wg.Done()
			topDomainsResponse, topDomainsErr = decodeJsonFromRequest[topDomainsResponseJson](client, topDomainsRequest)
		}()
	}

	wg.Wait()
	partialContent := false

	if statsErr != nil {
		return nil, "", fmt.Errorf("fetching stats: %v", statsErr)
	}

	if includeGraph && seriesErr != nil {
		slog.Error("Failed to fetch Pihole v6 graph data", "error", seriesErr)
		partialContent = true
	}

	if includeTopDomains && topDomainsErr != nil {
		slog.Error("Failed to fetch Pihole v6 top domains", "error", topDomainsErr)
		partialContent = true
	}

	stats := &dnsStats{
		TotalQueries:   statsResponse.Queries.Total,
		BlockedQueries: statsResponse.Queries.Blocked,
		BlockedPercent: int(statsResponse.Queries.PercentBlocked),
		DomainsBlocked: statsResponse.Gravity.DomainsBlocked,
	}

View on GitHub (pinned to 91324e8de7)

Solutions

  1. Check the wrapped error for status vs transport: 401 means session/auth trouble, timeouts mean load/network.
  2. curl -H 'X-Session: <sid>' {url}/api/stats after authenticating to verify the endpoint responds 200 JSON.
  3. Ensure the widget url is the Pi-hole base URL (no /admin path suffix for v6 API).
  4. If it happens only occasionally, rely on the widget's cache/retry on next page refresh.
Defensive patterns

Strategy: retry

Try / catch

stats, sid, err := fetchPiholeV6Stats(...)
if err != nil {
    if errors.Is(err, errPartialContent) {
        // graph/top-domains degraded but stats present: render with warning
    } else {
        // statsErr: fatal for this refresh; keep cached render and retry later
    }
}

Prevention

When it happens

Trigger: The main stats request (GET /api/stats with the session) returns non-2xx, times out, or returns undecodable JSON, while optional graph/top-domain goroutines may or may not have succeeded.

Common situations: Session invalidated server-side between auth and stats call; Pi-hole under load timing out; URL pointing to a path that 404s; proxy interference on /api/stats.

Related errors


AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15). Data as JSON: /api/errors/af075833fd6cb123. Report an issue: GitHub.