@@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -271,79 +271,6 @@ func DoRequestWithClient(ctx context.Context, client *http.Client, req *http.Req
|
|||||||
return client.Do(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.
|
// 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.
|
// 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.
|
// Reddit also sometimes sends errors with 200 codes; we check for those too.
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var timestampType = reflect.TypeOf(Timestamp{})
|
||||||
|
|
||||||
// String is a helper routine that allocates a new string value
|
// String is a helper routine that allocates a new string value
|
||||||
// to store v and returns a pointer to it.
|
// to store v and returns a pointer to it.
|
||||||
func String(v string) *string {
|
func String(v string) *string {
|
||||||
@@ -91,6 +93,12 @@ func stringifyStruct(w io.Writer, v reflect.Value) {
|
|||||||
_, _ = w.Write([]byte(v.Type().String()))
|
_, _ = 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{'{'})
|
_, _ = w.Write([]byte{'{'})
|
||||||
|
|
||||||
var sep bool
|
var sep bool
|
||||||
|
|||||||
Reference in New Issue
Block a user