From 522fe450eb341ac13477e252fc2235902d9ec5a9 Mon Sep 17 00:00:00 2001 From: tajniak81 <13187254+tajniak81@users.noreply.github.com> Date: Tue, 14 Jul 2026 12:23:31 +0200 Subject: [PATCH] Report keyless OpenWeather as degraded, not down MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../internal/plugins/builtin/openweather/openweather.go | 8 ++++++-- .../plugins/builtin/openweather/openweather_test.go | 7 ++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/API Server/internal/plugins/builtin/openweather/openweather.go b/API Server/internal/plugins/builtin/openweather/openweather.go index beaa7d4..5956de3 100644 --- a/API Server/internal/plugins/builtin/openweather/openweather.go +++ b/API Server/internal/plugins/builtin/openweather/openweather.go @@ -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("", "")) diff --git a/API Server/internal/plugins/builtin/openweather/openweather_test.go b/API Server/internal/plugins/builtin/openweather/openweather_test.go index 6d03ecc..3a02b68 100644 --- a/API Server/internal/plugins/builtin/openweather/openweather_test.go +++ b/API Server/internal/plugins/builtin/openweather/openweather_test.go @@ -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) } }