From 8fbbc9bc6b75d693b601f0ea9199c47abdece712 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 31 May 2018 14:15:36 +0000 Subject: [PATCH 1/2] Decode JSON body when Prometheus returns 400 to an api call 400 and 422 are documented error codes from Prometheus, so we should attempt to parse the error returned for both of them. Needed to change a test that was requiring the old behaviour - made it use 500 instead of 400. Signed-off-by: Bryan Boreham --- api/prometheus/v1/api.go | 11 ++++++++--- api/prometheus/v1/api_test.go | 14 +++++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index c41c0cf..192ba49 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -455,6 +455,11 @@ type apiResponse struct { Error string `json:"error"` } +func apiError(code int) bool { + // These are the codes that Prometheus sends when it returns an error. + return code == statusAPIError || code == http.StatusBadRequest +} + func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, error) { resp, body, err := c.Client.Do(ctx, req) if err != nil { @@ -463,7 +468,7 @@ func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, [ code := resp.StatusCode - if code/100 != 2 && code != statusAPIError { + if code/100 != 2 && !apiError(code) { return resp, body, &Error{ Type: ErrBadResponse, Msg: fmt.Sprintf("bad response code %d", resp.StatusCode), @@ -479,14 +484,14 @@ func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, [ } } - if (code == statusAPIError) != (result.Status == "error") { + if apiError(code) != (result.Status == "error") { err = &Error{ Type: ErrBadResponse, Msg: "inconsistent body for response code", } } - if code == statusAPIError && result.Status == "error" { + if apiError(code) && result.Status == "error" { err = &Error{ Type: result.ErrorType, Msg: result.Error, diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index 2fe6044..707d29a 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -606,7 +606,19 @@ func TestAPIClientDo(t *testing.T) { response: "bad json", err: &Error{ Type: ErrBadResponse, - Msg: "bad response code 400", + Msg: "bad response code 500", + }, + code: http.StatusInternalServerError, + }, + { + response: &apiResponse{ + Status: "error", + ErrorType: ErrBadData, + Error: "end timestamp must not be before start time", + }, + err: &Error{ + Type: ErrBadData, + Msg: "end timestamp must not be before start time", }, code: http.StatusBadRequest, }, From 04c03265357082e72685a5d14745b852e2331b5c Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 1 Jun 2018 16:52:44 +0000 Subject: [PATCH 2/2] Add non-nil Data because Go 1.7 needs it Signed-off-by: Bryan Boreham --- api/prometheus/v1/api_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index 707d29a..1f7fda7 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -613,6 +613,7 @@ func TestAPIClientDo(t *testing.T) { { response: &apiResponse{ Status: "error", + Data: json.RawMessage(`null`), ErrorType: ErrBadData, Error: "end timestamp must not be before start time", },