1
1
package coder
2
2
3
3
import (
4
+ "bytes"
4
5
"encoding/json"
5
6
"fmt"
7
+ "io"
6
8
"net/http"
7
9
8
10
"golang.org/x/xerrors"
@@ -29,11 +31,31 @@ type APIErrorMsg struct {
29
31
Details json.RawMessage `json:"details"`
30
32
}
31
33
34
+ // NewHTTPError reads the response body and stores metadata
35
+ // about the response in order to be unpacked into
36
+ // an *APIError.
37
+ func NewHTTPError (resp * http.Response ) * HTTPError {
38
+ var buf bytes.Buffer
39
+ _ , err := io .Copy (& buf , resp .Body )
40
+ if err != nil {
41
+ return & HTTPError {
42
+ cachedErr : err ,
43
+ }
44
+ }
45
+ return & HTTPError {
46
+ url : resp .Request .URL .String (),
47
+ statusCode : resp .StatusCode ,
48
+ body : buf .Bytes (),
49
+ }
50
+ }
51
+
32
52
// HTTPError represents an error from the Coder API.
33
53
type HTTPError struct {
34
- * http.Response
35
- cached * APIError
36
- cachedErr error
54
+ url string
55
+ statusCode int
56
+ body []byte
57
+ cached * APIError
58
+ cachedErr error
37
59
}
38
60
39
61
// Payload decode the response body into the standard error structure. The `details`
@@ -46,7 +68,7 @@ func (e *HTTPError) Payload() (*APIError, error) {
46
68
47
69
// Try to decode the payload as an error, if it fails or if there is no error message,
48
70
// return the response URL with the status.
49
- if err := json .NewDecoder (e .Response . Body ). Decode ( & msg ); err != nil {
71
+ if err := json .Unmarshal (e .body , & msg ); err != nil {
50
72
e .cachedErr = err
51
73
return nil , err
52
74
}
@@ -55,16 +77,16 @@ func (e *HTTPError) Payload() (*APIError, error) {
55
77
return & msg , nil
56
78
}
57
79
80
+ func (e * HTTPError ) StatusCode () int {
81
+ return e .statusCode
82
+ }
83
+
58
84
func (e * HTTPError ) Error () string {
59
85
apiErr , err := e .Payload ()
60
86
if err != nil || apiErr .Err .Msg == "" {
61
- return fmt .Sprintf ("%s: %d %s" , e .Request . URL , e .StatusCode , e . Status )
87
+ return fmt .Sprintf ("%s: %d %s" , e .url , e .statusCode , http . StatusText ( e . statusCode ) )
62
88
}
63
89
64
90
// If the payload was a in the expected error format with a message, include it.
65
91
return apiErr .Err .Msg
66
92
}
67
-
68
- func bodyError (resp * http.Response ) error {
69
- return & HTTPError {Response : resp }
70
- }
0 commit comments