forked from go-kivik/couchdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
errors.go
44 lines (39 loc) · 1.04 KB
/
errors.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
package chttp
import (
"encoding/json"
"fmt"
"mime"
"net/http"
)
// HTTPError is an error that represents an HTTP transport error.
type HTTPError struct {
Code int
Reason string `json:"reason"`
}
func (e *HTTPError) Error() string {
if e.Reason == "" {
return http.StatusText(e.Code)
}
return fmt.Sprintf("%s: %s", http.StatusText(e.Code), e.Reason)
}
// StatusCode returns the embedded status code.
func (e *HTTPError) StatusCode() int {
return e.Code
}
// ResponseError returns an error from an *http.Response.
func ResponseError(resp *http.Response) error {
if resp.StatusCode < 400 {
return nil
}
defer func() { _ = resp.Body.Close() }()
httpErr := &HTTPError{}
if resp.Request.Method != "HEAD" && resp.ContentLength != 0 {
if ct, _, _ := mime.ParseMediaType(resp.Header.Get("Content-Type")); ct == typeJSON {
if err := json.NewDecoder(resp.Body).Decode(httpErr); err != nil {
httpErr.Reason = fmt.Sprintf("unknown (failed to decode error response: %s)", err)
}
}
}
httpErr.Code = resp.StatusCode
return httpErr
}