Add errors.go

Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
Vartan Benohanian 2020-05-16 11:53:15 -04:00
parent 17b220b13c
commit 9d8e731294
3 changed files with 88 additions and 73 deletions

80
errors.go Normal file
View file

@ -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,
)
}

View file

@ -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.

View file

@ -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