Browse Source

Display HTTP errors from server

Upstreaming change from golang/go@39366326.

HTTP body will be read and displayed when both conditions are true:
* Response includes non-empty header "X-Go-Pprof".
* Content-Type is text/plain.
Kale Blankenship 8 years ago
parent
commit
a88ec1fbbf
2 changed files with 28 additions and 3 deletions
  1. 15
    1
      internal/driver/fetch.go
  2. 13
    2
      internal/symbolizer/symbolizer.go

+ 15
- 1
internal/driver/fetch.go View File

@@ -18,12 +18,14 @@ import (
18 18
 	"bytes"
19 19
 	"fmt"
20 20
 	"io"
21
+	"io/ioutil"
21 22
 	"net/http"
22 23
 	"net/url"
23 24
 	"os"
24 25
 	"os/exec"
25 26
 	"path/filepath"
26 27
 	"strconv"
28
+	"strings"
27 29
 	"sync"
28 30
 	"time"
29 31
 
@@ -391,12 +393,24 @@ func fetchURL(source string, timeout time.Duration) (io.ReadCloser, error) {
391 393
 		return nil, fmt.Errorf("http fetch: %v", err)
392 394
 	}
393 395
 	if resp.StatusCode != http.StatusOK {
394
-		return nil, fmt.Errorf("server response: %s", resp.Status)
396
+		defer resp.Body.Close()
397
+		return nil, statusCodeError(resp)
395 398
 	}
396 399
 
397 400
 	return resp.Body, nil
398 401
 }
399 402
 
403
+func statusCodeError(resp *http.Response) error {
404
+	if resp.Header.Get("X-Go-Pprof") != "" && strings.Contains(resp.Header.Get("Content-Type"), "text/plain") {
405
+		// error is from pprof endpoint
406
+		body, err := ioutil.ReadAll(resp.Body)
407
+		if err == nil {
408
+			return fmt.Errorf("server response: %s - %s", resp.Status, body)
409
+		}
410
+	}
411
+	return fmt.Errorf("server response: %s", resp.Status)
412
+}
413
+
400 414
 // isPerfFile checks if a file is in perf.data format. It also returns false
401 415
 // if it encounters an error during the check.
402 416
 func isPerfFile(path string) bool {

+ 13
- 2
internal/symbolizer/symbolizer.go View File

@@ -94,13 +94,24 @@ func postURL(source, post string) ([]byte, error) {
94 94
 	if err != nil {
95 95
 		return nil, fmt.Errorf("http post %s: %v", source, err)
96 96
 	}
97
+	defer resp.Body.Close()
97 98
 	if resp.StatusCode != http.StatusOK {
98
-		return nil, fmt.Errorf("server response: %s", resp.Status)
99
+		return nil, statusCodeError(resp)
99 100
 	}
100
-	defer resp.Body.Close()
101 101
 	return ioutil.ReadAll(resp.Body)
102 102
 }
103 103
 
104
+func statusCodeError(resp *http.Response) error {
105
+	if resp.Header.Get("X-Go-Pprof") != "" && strings.Contains(resp.Header.Get("Content-Type"), "text/plain") {
106
+		// error is from pprof endpoint
107
+		body, err := ioutil.ReadAll(resp.Body)
108
+		if err == nil {
109
+			return fmt.Errorf("server response: %s - %s", resp.Status, body)
110
+		}
111
+	}
112
+	return fmt.Errorf("server response: %s", resp.Status)
113
+}
114
+
104 115
 // doLocalSymbolize adds symbol and line number information to all locations
105 116
 // in a profile. mode enables some options to control
106 117
 // symbolization.