diff --git a/cloudapi/client.go b/cloudapi/client.go index 07ca6f99521f..5077266e79ba 100644 --- a/cloudapi/client.go +++ b/cloudapi/client.go @@ -144,7 +144,7 @@ func (c *Client) do(req *http.Request, v interface{}, attempt int) (retry bool, return false, err } - if err = checkResponse(resp); err != nil { + if err = CheckResponse(resp); err != nil { return false, err } @@ -157,7 +157,7 @@ func (c *Client) do(req *http.Request, v interface{}, attempt int) (retry bool, return false, err } -func checkResponse(r *http.Response) error { +func CheckResponse(r *http.Response) error { if r == nil { return errUnknown } diff --git a/output/cloud/expv2/metrics_client.go b/output/cloud/expv2/metrics_client.go index 8d604aa657f6..ed36550f20b6 100644 --- a/output/cloud/expv2/metrics_client.go +++ b/output/cloud/expv2/metrics_client.go @@ -13,6 +13,7 @@ import ( "github.com/sirupsen/logrus" "google.golang.org/protobuf/proto" + "go.k6.io/k6/cloudapi" "go.k6.io/k6/lib/consts" "go.k6.io/k6/output/cloud/expv2/pbcloud" ) @@ -98,8 +99,9 @@ func (mc *MetricsClient) Push(ctx context.Context, referenceID string, samples * defer func() { _ = resp.Body.Close() }() - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("response got an unexpected status code: %s", resp.Status) + + if err := cloudapi.CheckResponse(resp); err != nil { + return err } mc.logger.WithField("t", time.Since(start)).WithField("size", len(b)). Debug("Pushed the collected metrics to the Cloud service") diff --git a/output/cloud/expv2/metrics_client_test.go b/output/cloud/expv2/metrics_client_test.go index 4350514f1c99..8a23533a26ac 100644 --- a/output/cloud/expv2/metrics_client_test.go +++ b/output/cloud/expv2/metrics_client_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.k6.io/k6/cloudapi" "go.k6.io/k6/lib/testutils" "go.k6.io/k6/output/cloud/expv2/pbcloud" ) @@ -93,3 +94,31 @@ func TestMetricsClientPushError(t *testing.T) { err := mc.Push(context.TODO(), "test-ref-id", nil) assert.ErrorContains(t, err, "fake generated error") } + +func TestMetricsClientPushStructuredError(t *testing.T) { + t.Parallel() + + exp := cloudapi.ErrorResponse{Code: 1, Message: "test message"} + + httpClientMock := func(_ *http.Request) (*http.Response, error) { + b := `{"error":{"code":1,"message":"test message"}}` + r := &http.Response{ + StatusCode: http.StatusBadRequest, + Body: io.NopCloser(bytes.NewBuffer([]byte(b))), + } + exp.Response = r + return r, nil + } + + mc := MetricsClient{ + httpClient: httpDoerFunc(httpClientMock), + pushBufferPool: sync.Pool{ + New: func() interface{} { + return &bytes.Buffer{} + }, + }, + } + + err := mc.Push(context.TODO(), "test-ref-id", nil) + assert.Equal(t, exp, err) +}