Fix DoJSON error on empty-body 2xx response (#31801)

This commit is contained in:
andig 2026-07-15 09:23:04 +02:00 • committed by GitHub
parent 69f817d78c
commit 526d17ff4a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 63 additions and 1 deletions

View file

@ -3,6 +3,8 @@ package request
import (
"encoding/json"
"encoding/xml"
"errors"
"io"
"net/http"
"time"
@ -60,7 +62,12 @@ func decodeJSON(resp *http.Response, res any) error {
return err
}
return json.NewDecoder(resp.Body).Decode(&res)
// swallow io.EOF to allow empty response
if err := json.NewDecoder(resp.Body).Decode(&res); err != nil && !errors.Is(err, io.EOF) {
return err
}
return nil
}
// decodeXML reads HTTP response and decodes XML body if error is nil

View file

@ -0,0 +1,55 @@
package request
import (
"io"
"net/http"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type roundTripFunc func(req *http.Request) (*http.Response, error)
func (f roundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
return f(req)
}
func testHelper(status int, body string) *Helper {
return &Helper{
Client: &http.Client{
Transport: roundTripFunc(func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: status,
Body: io.NopCloser(strings.NewReader(body)),
Header: make(http.Header),
}, nil
}),
},
}
}
func TestDoJSON(t *testing.T) {
req, err := http.NewRequest(http.MethodGet, "http://example.com", nil)
require.NoError(t, err)
t.Run("empty body is not an error", func(t *testing.T) {
var res struct{ Code int }
err := testHelper(http.StatusOK, "").DoJSON(req, &res)
assert.NoError(t, err)
})
t.Run("valid body is decoded", func(t *testing.T) {
var res struct{ Code int }
err := testHelper(http.StatusOK, `{"Code":528}`).DoJSON(req, &res)
assert.NoError(t, err)
assert.Equal(t, 528, res.Code)
})
t.Run("truncated body is an error", func(t *testing.T) {
var res struct{ Code int }
err := testHelper(http.StatusOK, `{"Code":52`).DoJSON(req, &res)
assert.Error(t, err)
})
}