forked from vartanbeno/go-reddit
/
errors.go
105 lines (86 loc) · 2.33 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
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package reddit
import (
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
)
// APIError is an error coming from Reddit.
type APIError struct {
Label string
Reason string
Field string
}
func (e *APIError) Error() string {
return fmt.Sprintf("field %q caused %s: %s", e.Field, e.Label, e.Reason)
}
// UnmarshalJSON implements the json.Unmarshaler interface.
func (e *APIError) UnmarshalJSON(data []byte) error {
var info [3]string
err := json.Unmarshal(data, &info)
if err != nil {
return err
}
e.Label = info[0]
e.Reason = info[1]
e.Field = info[2]
return nil
}
// JSONErrorResponse is an error response that sometimes gets returned with a 200 code.
type JSONErrorResponse struct {
// HTTP response that caused this error.
Response *http.Response `json:"-"`
JSON struct {
Errors []APIError `json:"errors,omitempty"`
} `json:"json"`
}
func (r *JSONErrorResponse) Error() string {
errorMessages := make([]string, len(r.JSON.Errors))
for i, err := range r.JSON.Errors {
errorMessages[i] = err.Error()
}
return fmt.Sprintf(
"%s %s: %d %s",
r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, strings.Join(errorMessages, ";"),
)
}
// An ErrorResponse reports the error caused by an API request
type ErrorResponse struct {
// HTTP response that caused this error
Response *http.Response `json:"-"`
// Error message
Message string `json:"message"`
}
func (r *ErrorResponse) Error() string {
return fmt.Sprintf(
"%s %s: %d %s",
r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, r.Message,
)
}
// RateLimitError occurs when the client is sending too many requests to Reddit in a given time frame.
type RateLimitError struct {
// Rate specifies the last known rate limit for the client
Rate Rate
// HTTP response that caused this error
Response *http.Response
// Error message
Message string
}
func (e *RateLimitError) Error() string {
return fmt.Sprintf(
"%s %s: %d %s %s",
e.Response.Request.Method, e.Response.Request.URL, e.Response.StatusCode, e.Message, e.formateRateReset(),
)
}
func (e *RateLimitError) formateRateReset() string {
d := time.Until(e.Rate.Reset).Round(time.Second)
isNegative := d < 0
if isNegative {
d *= -1
}
if isNegative {
return fmt.Sprintf("[rate limit was reset %s ago]", d)
}
return fmt.Sprintf("[rate limit will reset in %s]", d)
}