Report keyless OpenWeather as degraded, not down

The panel health probe tests the global plugin config only. When the
plugin is enabled as a master switch with no global API key (users supply
their own), the probe reported a hard "down", which read as broken.

Return "degraded" with an explanatory detail instead — a keyless master
switch is a valid setup, nothing is failing. The Web App user-facing path
is unchanged: a caller whose effective key is empty still gets "down" with
an actionable "add one to connect" message before the plugin is called.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
tajniak81
2026-07-14 12:23:31 +02:00
co-authored by Claude Opus 4.8
parent 6d73c89cc8
commit 522fe450eb
2 changed files with 10 additions and 5 deletions
@@ -259,8 +259,12 @@ func (p *Plugin) HealthCheck(ctx context.Context) plugins.Health {
key := p.apiKey
p.mu.Unlock()
if key == "" {
return plugins.Health{Status: plugins.StatusDown, LatencyMs: time.Since(start).Milliseconds(),
Detail: errNoKey.Error()}
// No key at this (global) layer. This is a valid configuration: the plugin
// acts as a master switch and organizations/users supply their own key in
// the Web App. Report degraded rather than down — nothing is broken, the
// global layer just can't self-probe without a key.
return plugins.Health{Status: plugins.StatusDegraded, LatencyMs: time.Since(start).Milliseconds(),
Detail: "no global API key — master switch only; organizations and users supply their own key"}
}
target := p.requestURL("/data/2.5/weather", p.pointQuery("", ""))
@@ -101,12 +101,13 @@ func TestRequestURLNoKey(t *testing.T) {
}
}
// TestHealthCheckNoKey confirms a missing key is reported as down, not a panic.
// TestHealthCheckNoKey confirms a missing key is reported as degraded (a valid
// master-switch config, not a hard failure), not a panic.
func TestHealthCheckNoKey(t *testing.T) {
p := &Plugin{}
_ = p.Init(context.Background(), nil)
if h := p.HealthCheck(context.Background()); h.Status != plugins.StatusDown {
t.Errorf("status = %q, want down (detail=%q)", h.Status, h.Detail)
if h := p.HealthCheck(context.Background()); h.Status != plugins.StatusDegraded {
t.Errorf("status = %q, want degraded (detail=%q)", h.Status, h.Detail)
}
}