From 9d8e731294fa3a2b00be95e02f48b490ad1e8f0f Mon Sep 17 00:00:00 2001 From: Vartan Benohanian Date: Sat, 16 May 2020 11:53:15 -0400 Subject: [PATCH] Add errors.go Signed-off-by: Vartan Benohanian --- errors.go | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ geddit.go | 73 -------------------------------------------------- util.go | 8 ++++++ 3 files changed, 88 insertions(+), 73 deletions(-) create mode 100644 errors.go diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..c796abb --- /dev/null +++ b/errors.go @@ -0,0 +1,80 @@ +package geddit + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// RedditError is an error coming from Reddit +type RedditError struct { + Label string + Reason string + Field string +} + +func (e *RedditError) Error() string { + return fmt.Sprintf("%s: %s because of field %q", e.Label, e.Reason, e.Field) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (e *RedditError) UnmarshalJSON(data []byte) error { + var info []string + + err := json.Unmarshal(data, &info) + if err != nil { + return err + } + + if len(info) != 3 { + return fmt.Errorf("got unexpected Reddit error: %v", info) + } + + 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 []RedditError `json:"errors,omitempty"` + } `json:"json,omitempty"` +} + +func (r *JSONErrorResponse) Error() string { + var message string + if r.JSON != nil && len(r.JSON.Errors) > 0 { + for i, err := range r.JSON.Errors { + message += err.Error() + if i < len(r.JSON.Errors)-1 { + message += ";" + } + } + } + return fmt.Sprintf( + "%v %v: %d %v", + r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, message, + ) +} + +// 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( + "%v %v: %d %v", + r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, r.Message, + ) +} diff --git a/geddit.go b/geddit.go index e3d575e..9fb0cdd 100644 --- a/geddit.go +++ b/geddit.go @@ -271,79 +271,6 @@ func DoRequestWithClient(ctx context.Context, client *http.Client, req *http.Req return client.Do(req) } -// 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 []RedditError `json:"errors,omitempty"` - } `json:"json,omitempty"` -} - -// RedditError is an error coming from Reddit -type RedditError struct { - Label string - Reason string - Field string -} - -func (e *RedditError) Error() string { - return fmt.Sprintf("%s: %s because of field %q", e.Label, e.Reason, e.Field) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (e *RedditError) UnmarshalJSON(data []byte) error { - var info []string - - err := json.Unmarshal(data, &info) - if err != nil { - return err - } - - if len(info) != 3 { - return fmt.Errorf("got unexpected Reddit error: %v", info) - } - - e.Label = info[0] - e.Reason = info[1] - e.Field = info[2] - - return nil -} - -func (r *JSONErrorResponse) Error() string { - var message string - if r.JSON != nil && len(r.JSON.Errors) > 0 { - for i, err := range r.JSON.Errors { - message += err.Error() - if i < len(r.JSON.Errors)-1 { - message += ";" - } - } - } - return fmt.Sprintf( - "%v %v: %d %v", - r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, message, - ) -} - -// An ErrorResponse reports the error caused by an API request -type ErrorResponse struct { - // HTTP response that caused this error - Response *http.Response - - // Error 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, - ) -} - // 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. // Reddit also sometimes sends errors with 200 codes; we check for those too. diff --git a/util.go b/util.go index 59e65c6..b8a5b71 100644 --- a/util.go +++ b/util.go @@ -7,6 +7,8 @@ import ( "reflect" ) +var timestampType = reflect.TypeOf(Timestamp{}) + // String is a helper routine that allocates a new string value // to store v and returns a pointer to it. func String(v string) *string { @@ -91,6 +93,12 @@ func stringifyStruct(w io.Writer, v reflect.Value) { _, _ = w.Write([]byte(v.Type().String())) } + // special handling of Timestamp values + if v.Type() == timestampType { + fmt.Fprintf(w, "{%s}", v.Interface()) + return + } + _, _ = w.Write([]byte{'{'}) var sep bool