Repository: qiniu/goc (go)

Issue:
Errors should show in command instead of output files when get a profile
If errors occur when we use `goc profile --output output.txt` to get a profile, we found that there is nothing warning on the terminal screen. But the errors appeared unexpectedly in the output file.

Pull request description:
Errors will show in command instead of output files when get a profile
fix #72 

Patch:
diff --git a/pkg/cover/client.go b/pkg/cover/client.go
index 6567d8b..361d62d 100644
--- a/pkg/cover/client.go
+++ b/pkg/cover/client.go
@@ -76,15 +76,15 @@ func (c *client) RegisterService(srv Service) ([]byte, error) {
 		return nil, fmt.Errorf("invalid service name")
 	}
 	u := fmt.Sprintf("%s%s?name=%s&address=%s", c.Host, CoverRegisterServiceAPI, srv.Name, srv.Address)
-	res, err := c.do("POST", u, nil)
+	_, res, err := c.do("POST", u, nil)
 	return res, err
 }
 
 func (c *client) ListServices() ([]byte, error) {
 	u := fmt.Sprintf("%s%s", c.Host, CoverServicesListAPI)
-	services, err := c.do("GET", u, nil)
+	_, services, err := c.do("GET", u, nil)
 	if err != nil && isNetworkError(err) {
-		services, err = c.do("GET", u, nil)
+		_, services, err = c.do("GET", u, nil)
 	}
 
 	return services, err
@@ -102,42 +102,46 @@ func (c *client) Profile(param ProfileParam) ([]byte, error) {
 	for _, addr := range param.Address {
 		u = u + "&address=" + addr
 	}
-	profile, err := c.do("GET", u, nil)
+	res, profile, err := c.do("GET", u, nil)
 	if err != nil && isNetworkError(err) {
-		profile, err = c.do("GET", u, nil)
+		res, profile, err = c.do("GET", u, nil)
+	}
+	if err == nil && res.StatusCode != 200 {
+		err = fmt.Errorf(string(profile))
 	}
 	return profile, err
 }
 
 func (c *client) Clear() ([]byte, error) {
 	u := fmt.Sprintf("%s%s", c.Host, CoverProfileClearAPI)
-	resp, err := c.do("POST", u, nil)
+	_, resp, err := c.do("POST", u, nil)
 	if err != nil && isNetworkError(err) {
-		resp, err = c.do("POST", u, nil)
+		_, resp, err = c.do("POST", u, nil)
 	}
 	return resp, err
 }
 
 func (c *client) InitSystem() ([]byte, error) {
 	u := fmt.Sprintf("%s%s", c.Host, CoverInitSystemAPI)
-	return c.do("POST", u, nil)
+	_, body, err := c.do("POST", u, nil)
+	return body, err
 }
 
-func (c *client) do(method, url string, body io.Reader) ([]byte, error) {
+func (c *client) do(method, url string, body io.Reader) (*http.Response, []byte, error) {
 	req, err := http.NewRequest(method, url, body)
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	res, err := c.client.Do(req)
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	defer res.Body.Close()
 	responseBody, err := ioutil.ReadAll(res.Body)
 	if err != nil {
-		return nil, err
+		return res, nil, err
 	}
-	return responseBody, nil
+	return res, responseBody, nil
 }
 
 func isNetworkError(err error) bool {


Test patch:
diff --git a/pkg/cover/client_test.go b/pkg/cover/client_test.go
index 1693569..6ce7fee 100644
--- a/pkg/cover/client_test.go
+++ b/pkg/cover/client_test.go
@@ -115,7 +115,7 @@ func TestClientAction(t *testing.T) {
 		assert.Contains(t, string(res), "success")
 		res, err = client.Profile(item.param)
 		if err != nil {
-			assert.Equal(t, err.Error(), item.res)
+			assert.Contains(t, err.Error(), item.res)
 		} else {
 			assert.Contains(t, string(res), item.res)
 		}
@@ -157,3 +157,11 @@ func TestClientListServices(t *testing.T) {
 	_, err := c.ListServices()
 	assert.Contains(t, err.Error(), "connect: connection refused")
 }
+
+func TestClientDo(t *testing.T) {
+	c := &client{
+		client: http.DefaultClient,
+	}
+	_, _, err := c.do(" ", "http://127.0.0.1:7777", nil) // a invalid method
+	assert.Contains(t, err.Error(), "invalid method")
+}