瀏覽代碼

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 年之前
父節點
當前提交
a88ec1fbbf
共有 2 個檔案被更改,包括 28 行新增3 行删除
  1. 15
    1
      internal/driver/fetch.go
  2. 13
    2
      internal/symbolizer/symbolizer.go

+ 15
- 1
internal/driver/fetch.go 查看文件

18
 	"bytes"
18
 	"bytes"
19
 	"fmt"
19
 	"fmt"
20
 	"io"
20
 	"io"
21
+	"io/ioutil"
21
 	"net/http"
22
 	"net/http"
22
 	"net/url"
23
 	"net/url"
23
 	"os"
24
 	"os"
24
 	"os/exec"
25
 	"os/exec"
25
 	"path/filepath"
26
 	"path/filepath"
26
 	"strconv"
27
 	"strconv"
28
+	"strings"
27
 	"sync"
29
 	"sync"
28
 	"time"
30
 	"time"
29
 
31
 
391
 		return nil, fmt.Errorf("http fetch: %v", err)
393
 		return nil, fmt.Errorf("http fetch: %v", err)
392
 	}
394
 	}
393
 	if resp.StatusCode != http.StatusOK {
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
 	return resp.Body, nil
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
 // isPerfFile checks if a file is in perf.data format. It also returns false
414
 // isPerfFile checks if a file is in perf.data format. It also returns false
401
 // if it encounters an error during the check.
415
 // if it encounters an error during the check.
402
 func isPerfFile(path string) bool {
416
 func isPerfFile(path string) bool {

+ 13
- 2
internal/symbolizer/symbolizer.go 查看文件

94
 	if err != nil {
94
 	if err != nil {
95
 		return nil, fmt.Errorf("http post %s: %v", source, err)
95
 		return nil, fmt.Errorf("http post %s: %v", source, err)
96
 	}
96
 	}
97
+	defer resp.Body.Close()
97
 	if resp.StatusCode != http.StatusOK {
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
 	return ioutil.ReadAll(resp.Body)
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
 // doLocalSymbolize adds symbol and line number information to all locations
115
 // doLocalSymbolize adds symbol and line number information to all locations
105
 // in a profile. mode enables some options to control
116
 // in a profile. mode enables some options to control
106
 // symbolization.
117
 // symbolization.