Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions json_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,18 @@ func ReadResponse(r io.Reader, v interface{}) error {
_, err := ReadResponsePage(r, v)
return err
}

// ReadError attempts to unmarshal JSON-encoded error details from the supplied reader. It returns
// nil if an error could not be parsed from the response, or if the parsed error was nil.
func ReadError(r io.Reader) error {
var u struct {
Error *Error `json:"error"`
}
if err := json.NewDecoder(r).Decode(&u); err != nil {
return nil
}
if u.Error == nil {
return nil
}
return u.Error
}
54 changes: 46 additions & 8 deletions json_response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,15 +284,14 @@ func TestReadResponseNil(t *testing.T) {
}

tests := []struct {
name string
r io.Reader
wantErr bool
wantValue string
name string
r io.Reader
wantErr bool
}{
{"Empty", bytes.NewReader(nil), true, ""},
{"Nil", getResponseBody(nil), false, "blah"},
{"Response", getResponseBody(TestStruct{"blah"}), false, "blah"},
{"Error", getErrorBody("blah", http.StatusNotFound), true, ""},
{"Empty", bytes.NewReader(nil), true},
{"Nil", getResponseBody(nil), false},
{"Response", getResponseBody(TestStruct{"blah"}), false},
{"Error", getErrorBody("blah", http.StatusNotFound), true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand All @@ -303,3 +302,42 @@ func TestReadResponseNil(t *testing.T) {
})
}
}

func TestReadError(t *testing.T) {
type TestStruct struct {
Value string
}

tests := []struct {
name string
r io.Reader
wantErr bool
wantMessage string
wantCode int
}{
{"Empty", bytes.NewReader(nil), false, "", 0},
{"Response", getResponseBody(TestStruct{"blah"}), false, "", 0},
{"Error", getErrorBody("blah", http.StatusNotFound), true, "blah", http.StatusNotFound},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ReadError(tt.r)
if (err != nil) != tt.wantErr {
t.Errorf("ReadError() error = %v, wantErr %v", err, tt.wantErr)
}

if err != nil {
err, ok := err.(*Error)
if !ok {
t.Fatal("invalid error type")
}
if got, want := err.Message, tt.wantMessage; got != want {
t.Errorf("got message %v, want %v", got, want)
}
if got, want := err.Code, tt.wantCode; got != want {
t.Errorf("got code %v, want %v", got, want)
}
}
})
}
}