Merge pull request #414 from bboreham/decode-400s

Decode JSON body when Prometheus returns 400 to an api call
This commit is contained in:
Björn Rabenstein 2018-06-04 15:00:09 +02:00 committed by GitHub
commit 7540c07074
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 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,20 @@ 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",
Data: json.RawMessage(`null`),
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,
}, },