From 90f902c3ab312eeb9de2fc7a8b9f6852e2c2bcec Mon Sep 17 00:00:00 2001 From: Marcin Owsiany Date: Fri, 12 Oct 2018 09:13:12 +0200 Subject: [PATCH] Add a way to return the body of a 5xx response. Fixes: #479. Signed-off-by: Marcin Owsiany --- api/prometheus/v1/api.go | 10 ++++---- api/prometheus/v1/api_test.go | 44 +++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index 6a19fac12..702a78e94 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -69,8 +69,9 @@ const ( // Error is an error returned by the API. type Error struct { - Type ErrorType - Msg string + Type ErrorType + Msg string + Detail string } func (e *Error) Error() string { @@ -470,8 +471,9 @@ func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, [ if code/100 != 2 && !apiError(code) { return resp, body, &Error{ - Type: ErrBadResponse, - Msg: fmt.Sprintf("bad response code %d", resp.StatusCode), + Type: ErrBadResponse, + Msg: fmt.Sprintf("bad response code %d", resp.StatusCode), + Detail: string(body), } } diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index 1f7fda7f9..58ae38746 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -30,15 +30,17 @@ import ( ) type apiTest struct { - do func() (interface{}, error) - inErr error - inRes interface{} + do func() (interface{}, error) + inErr error + inCode int + inRes interface{} reqPath string reqParam url.Values reqMethod string res interface{} err error + errCheck func(error) error } type apiTestClient struct { @@ -75,7 +77,9 @@ func (c *apiTestClient) Do(ctx context.Context, req *http.Request) (*http.Respon } resp := &http.Response{} - if test.inErr != nil { + if test.inCode != 0 { + resp.StatusCode = test.inCode + } else if test.inErr != nil { resp.StatusCode = statusAPIError } else { resp.StatusCode = http.StatusOK @@ -194,6 +198,30 @@ func TestAPIs(t *testing.T) { }, err: fmt.Errorf("some error"), }, + { + do: doQuery("2", testTime), + inRes: "some body", + inCode: 500, + inErr: &Error{ + Type: ErrBadResponse, + Msg: "bad response code: 500", + Detail: "a body", + }, + + reqMethod: "GET", + reqPath: "/api/v1/query", + reqParam: url.Values{ + "query": []string{"2"}, + "time": []string{testTime.Format(time.RFC3339Nano)}, + }, + errCheck: func(err error) error { + apiErr := err.(*Error) + if apiErr.Detail != "a body" { + return fmt.Errorf("%q should be %q", apiErr.Detail, "a body") + } + return nil + }, + }, { do: doQueryRange("2", Range{ @@ -503,7 +531,13 @@ func TestAPIs(t *testing.T) { res, err := test.do() - if test.err != nil { + if test.errCheck != nil { + err = test.errCheck(err) + if err != nil { + t.Errorf("returned error is wrong: %s", err) + } + continue + } else if test.err != nil { if err == nil { t.Errorf("expected error %q but got none", test.err) continue