diff --git a/plugin/http.go b/plugin/http.go index 5d54ec8b3..67088e348 100644 --- a/plugin/http.go +++ b/plugin/http.go @@ -226,22 +226,25 @@ func (p *HTTP) request(url string, body string) ([]byte, error) { return nil, err } + val, err := request.ReadBody(resp) + if err != nil { + if err2 := knownErrors(val); err2 != nil { + err = err2 + } + + return val, err + } + // warn on uncached GET polling: a repeated roundtrip means neither a configured // cache nor the device's own response headers spared it. cache hits are exempt. + // only successful responses count, a failed one is retried by the caller if p.method == http.MethodGet && p.mu == nil && resp.Header.Get(httpcache.XFromCache) == "" { if repeatedGet(url, time.Now()) { p.log.WARN.Printf("uncached request repeated within 1s, please report at https://github.com/evcc-io/evcc/issues: %s", url) } } - val, err := request.ReadBody(resp) - if err != nil { - if err2 := knownErrors(val); err2 != nil { - err = err2 - } - } - - return val, err + return val, nil } type httpAccess struct { diff --git a/plugin/http_test.go b/plugin/http_test.go index e71c65da1..543a80257 100644 --- a/plugin/http_test.go +++ b/plugin/http_test.go @@ -164,6 +164,27 @@ func (suite *httpTestSuite) TestSetPath() { suite.Require().Equal("/foo/bar/4711", suite.h.req.URL.String()) } +func TestRepeatedGetFailed(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + http.Error(w, "nope", http.StatusInternalServerError) + })) + defer srv.Close() + + p := NewHTTP(util.NewLogger("foo"), http.MethodGet, srv.URL, false, 0) + g, err := p.StringGetter() + require.NoError(t, err) + + // a failing request is retried by the caller, it must not count as a sighting + for range 2 { + _, err := g() + require.Error(t, err) + } + + httpSeenMu.Lock() + defer httpSeenMu.Unlock() + require.NotContains(t, httpSeen, srv.URL) +} + func TestRepeatedGet(t *testing.T) { url := "http://repeated.test/uncached" t0 := time.Now()