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 <bjboreham@gmail.com>
This commit is contained in:
Bryan Boreham 2018-05-31 14:15:36 +00:00
parent a62824bd1b
commit 8fbbc9bc6b
2 changed files with 21 additions and 4 deletions

View File

@ -455,6 +455,11 @@ type apiResponse struct {
Error string `json:"error"` 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) { func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, error) {
resp, body, err := c.Client.Do(ctx, req) resp, body, err := c.Client.Do(ctx, req)
if err != nil { if err != nil {
@ -463,7 +468,7 @@ func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, [
code := resp.StatusCode code := resp.StatusCode
if code/100 != 2 && code != statusAPIError { if code/100 != 2 && !apiError(code) {
return resp, body, &Error{ return resp, body, &Error{
Type: ErrBadResponse, Type: ErrBadResponse,
Msg: fmt.Sprintf("bad response code %d", resp.StatusCode), 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{ err = &Error{
Type: ErrBadResponse, Type: ErrBadResponse,
Msg: "inconsistent body for response code", Msg: "inconsistent body for response code",
} }
} }
if code == statusAPIError && result.Status == "error" { if apiError(code) && result.Status == "error" {
err = &Error{ err = &Error{
Type: result.ErrorType, Type: result.ErrorType,
Msg: result.Error, Msg: result.Error,

View File

@ -606,7 +606,19 @@ func TestAPIClientDo(t *testing.T) {
response: "bad json", response: "bad json",
err: &Error{ err: &Error{
Type: ErrBadResponse, 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, code: http.StatusBadRequest,
}, },