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, },