-
Notifications
You must be signed in to change notification settings - Fork 2
/
responses.go
75 lines (61 loc) · 1.8 KB
/
responses.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package multivers
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
)
// CheckResponse checks the API response for errors, and returns them if present. A response is considered an
// error if it has a status code outside the 200 range. API error responses are expected to have either no response
// body, or a XML response body that maps to ErrorResponse. Any other response body will be silently ignored.
func CheckResponse(r *http.Response) error {
if c := r.StatusCode; c >= 200 && c <= 299 {
// status code is ok: no errors
return nil
}
// create base error response
errorResponse := &ErrorResponse{Response: r, Code: r.StatusCode}
// check if content type is json
err := checkContentType(r)
if err != nil {
errorResponse.Message = err.Error()
return errorResponse
}
// read response body
data, err := ioutil.ReadAll(r.Body)
if err != nil {
return errorResponse
}
// no data returned: error
if len(data) == 0 {
return errorResponse
}
// convert json to struct
err = json.Unmarshal(data, errorResponse)
if err != nil {
errorResponse.Message = fmt.Sprintf("Malformed json response")
return errorResponse
}
return errorResponse
}
type ErrorResponse struct {
// HTTP response that caused this error
Response *http.Response
// HTTP status code
Code int
// Fault message
Message string `json:"Message"`
}
func (r *ErrorResponse) Error() string {
return fmt.Sprintf("%v %v: %d (%v)",
r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, r.Message)
}
func checkContentType(response *http.Response) error {
header := response.Header.Get("Content-Type")
contentType := strings.Split(header, ";")[0]
if contentType != "application/json" {
return fmt.Errorf("Expected Content-Type \"application/json\", got \"%s\"", contentType)
}
return nil
}