From c5a2e74d5197d3ffdf6c3e6ca134a4be4cac31eb Mon Sep 17 00:00:00 2001 From: Martin Helmich Date: Fri, 15 Jul 2022 13:05:50 +0200 Subject: [PATCH] Correctly process "text/plain" error responses --- client_test.go | 21 +++++++++++++++++++++ pdnshttp/client.go | 30 +++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/client_test.go b/client_test.go index bf1c64a..61ac90c 100644 --- a/client_test.go +++ b/client_test.go @@ -144,6 +144,27 @@ func TestCreateZone(t *testing.T) { assert.Equal(t, "example.de.", created.Name) } +func TestCreateZoneProducedReadableErrorMessages(t *testing.T) { + c := buildClient(t) + + zone := zones.Zone{ + Name: "test-error-message.de.", + Type: zones.ZoneTypeZone, + Kind: zones.ZoneKindNative, + Nameservers: []string{"ns1.example.com.", "ns2.example.com."}, + } + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + _, err := c.Zones().CreateZone(ctx, "localhost", zone) + require.Nil(t, err, "CreateZone returned error") + + _, err2 := c.Zones().CreateZone(ctx, "localhost", zone) + require.Error(t, err2, "CreateZone should return error") + require.Equal(t, "unexpected status code 409: http://localhost:8081/api/v1/servers/localhost/zones Conflict", err2.Error()) +} + func TestDeleteZone(t *testing.T) { c := buildClient(t) diff --git a/pdnshttp/client.go b/pdnshttp/client.go index 6ae617e..7c9bd92 100644 --- a/pdnshttp/client.go +++ b/pdnshttp/client.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "io" + "io/ioutil" "net/http" "net/http/httputil" "strings" @@ -88,18 +89,33 @@ func (c *Client) Do(ctx context.Context, req *http.Request, out interface{}) err if res.StatusCode == http.StatusNotFound { return ErrNotFound{URL: req.URL.String()} } else if res.StatusCode >= 400 { - // Get a human readable error message - // from PowerDNS API response - var er ErrResponse + if res.Header.Get("Content-Type") == "application/json" { + // Get a human readable error message + // from PowerDNS API response + var er ErrResponse + + if err := json.NewDecoder(res.Body).Decode(&er); err != nil { + return err + } + + return ErrUnexpectedStatus{ + URL: req.URL.String(), + StatusCode: res.StatusCode, + ErrResponse: er, + } + } - if err := json.NewDecoder(res.Body).Decode(&er); err != nil { + body, err := ioutil.ReadAll(res.Body) + if err != nil { return err } return ErrUnexpectedStatus{ - URL: req.URL.String(), - StatusCode: res.StatusCode, - ErrResponse: er, + URL: req.URL.String(), + StatusCode: res.StatusCode, + ErrResponse: ErrResponse{ + Message: string(body), + }, } }