@cryptotaxi247 / kubo / commits / 1b81f2ef1

add extended error handling

fixes #19 This commit was moved from ipfs/go-ipfs-http-client@8e3552ac1e6ea18ffd5f49918eef578de2b224fb

Steven Allen committed Jun 11, 2019 at 17:41 UTC 1b81f2ef10c40b5ba5a50ae545a62cc050c11813
1 file changed +61 -1
client/httpapi/response.go
+61 -1
@@ -13,6 +13,48 @@ import (
13 "os"
14 )
15
16 +// Error codes adapted from go-ipfs-cmds. We should find a better solution.
17 +
18 +// ErrorType signfies a category of errors
19 +type ErrorType uint
20 +
21 +// ErrorTypes convey what category of error ocurred
22 +const (
23 + // ErrNormal is a normal error. The command failed for some reason that's not a bug.
24 + ErrNormal ErrorType = iota
25 + // ErrClient means the client made an invalid request.
26 + ErrClient
27 + // ErrImplementation means there's a bug in the implementation.
28 + ErrImplementation
29 + // ErrRateLimited is returned when the operation has been rate-limited.
30 + ErrRateLimited
31 + // ErrForbidden is returned when the client doesn't have permission to
32 + // perform the requested operation.
33 + ErrForbidden
34 +)
35 +
36 +func (e ErrorType) Error() string {
37 + return e.String()
38 +}
39 +
40 +func (e ErrorType) String() string {
41 + switch e {
42 + case ErrNormal:
43 + return "command failed"
44 + case ErrClient:
45 + return "invalid argument"
46 + case ErrImplementation:
47 + return "internal error"
48 + case ErrRateLimited:
49 + return "rate limited"
50 + case ErrForbidden:
51 + return "request forbidden"
52 + default:
53 + return "unknown error code"
54 + }
55 +
56 +}
57 +
58 type trailerReader struct {
59 resp *http.Response
60 }
@@ -77,7 +119,13 @@ func (r *Response) decode(dec interface{}) error {
119 type Error struct {
120 Command string
121 Message string
80 - Code int
122 + Code ErrorType
123 +}
124 +
125 +// Unwrap returns the base error (an ErrorType). Works with go 1.14 error
126 +// helpers.
127 +func (e *Error) Unwrap() error {
128 + return e.Code
129 }
130
131 func (e *Error) Error() string {
@@ -133,11 +181,23 @@ func (r *Request) Send(c *http.Client) (*Response, error) {
181 fmt.Fprintf(os.Stderr, "ipfs-shell: warning! response (%d) read error: %s\n", resp.StatusCode, err)
182 }
183 e.Message = string(out)
184 +
185 + // set special status codes.
186 + switch resp.StatusCode {
187 + case http.StatusNotFound, http.StatusBadRequest:
188 + e.Code = ErrClient
189 + case http.StatusTooManyRequests:
190 + e.Code = ErrRateLimited
191 + case http.StatusForbidden:
192 + e.Code = ErrForbidden
193 + }
194 case contentType == "application/json":
195 if err = json.NewDecoder(resp.Body).Decode(e); err != nil {
196 fmt.Fprintf(os.Stderr, "ipfs-shell: warning! response (%d) unmarshall error: %s\n", resp.StatusCode, err)
197 }
198 default:
199 + // This is a server-side bug (probably).
200 + e.Code = ErrImplementation
201 fmt.Fprintf(os.Stderr, "ipfs-shell: warning! unhandled response (%d) encoding: %s", resp.StatusCode, contentType)
202 out, err := ioutil.ReadAll(resp.Body)
203 if err != nil {