-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #63 from messagebird/fix-voice-error-response
Fix voice error response
- Loading branch information
Showing
6 changed files
with
233 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"data": null, | ||
"errors": [ | ||
{ | ||
"code": 13, | ||
"message": "some-error" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"data": null, | ||
"errors": [ | ||
{ | ||
"code": 11, | ||
"message": "some-error" | ||
}, | ||
{ | ||
"code": 15, | ||
"message": "other-error" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,52 @@ | ||
package voice | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/messagebird/go-rest-api" | ||
) | ||
|
||
const apiRoot = "https://voice.messagebird.com" | ||
|
||
type ErrorResponse struct { | ||
Errors []Error | ||
} | ||
|
||
type Error struct { | ||
Code int | ||
Message string | ||
} | ||
|
||
func init() { | ||
// The Voice API returns errors in a format that slightly differs from other | ||
// APIs. Here we instruct package messagebird to use our custom | ||
// voice.errorReader func, which has access to voice.ErrorResponse, to | ||
// unmarshal those. Package messagebird must not import the voice package to | ||
// safeguard against import cycles, so it can not use voice.ErrorResponse | ||
// directly. | ||
messagebird.SetVoiceErrorReader(errorReader) | ||
} | ||
|
||
// errorReader takes a []byte representation of a Voice API JSON error and | ||
// parses it to a voice.ErrorResponse. | ||
func errorReader(b []byte) error { | ||
var er ErrorResponse | ||
if err := json.Unmarshal(b, &er); err != nil { | ||
return fmt.Errorf("encoding/json: Unmarshal: %v", err) | ||
} | ||
return er | ||
} | ||
|
||
func (e ErrorResponse) Error() string { | ||
errStrings := make([]string, len(e.Errors)) | ||
for i, v := range e.Errors { | ||
errStrings[i] = v.Error() | ||
} | ||
return strings.Join(errStrings, "; ") | ||
} | ||
|
||
func (e Error) Error() string { | ||
return fmt.Sprintf("code: %d, message: %q", e.Code, e.Message) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package voice | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/messagebird/go-rest-api/internal/mbtest" | ||
) | ||
|
||
func TestErrorReader(t *testing.T) { | ||
t.Run("Single error", func(t *testing.T) { | ||
b := mbtest.Testdata(t, "error.json") | ||
err := errorReader(b).(ErrorResponse) | ||
|
||
if count := len(err.Errors); count != 1 { | ||
t.Fatalf("Got %d, expected 1", count) | ||
} | ||
|
||
if err.Errors[0].Code != 13 { | ||
t.Errorf("Got %d, expected 13", err.Errors[0].Code) | ||
} | ||
if err.Errors[0].Message != "some-error" { | ||
t.Errorf("Got %q, expected some-error", err.Errors[0].Message) | ||
} | ||
}) | ||
|
||
t.Run("Multiple errors", func(t *testing.T) { | ||
b := mbtest.Testdata(t, "errors.json") | ||
err := errorReader(b).(ErrorResponse) | ||
|
||
if count := len(err.Errors); count != 2 { | ||
t.Fatalf("Got %d, expected 2", count) | ||
} | ||
|
||
if err.Errors[0].Code != 11 { | ||
t.Errorf("Got %d, expected 11", err.Errors[0].Code) | ||
} | ||
if err.Errors[0].Message != "some-error" { | ||
t.Errorf("Got %q, expected some-error", err.Errors[0].Message) | ||
} | ||
if err.Errors[1].Code != 15 { | ||
t.Errorf("Got %d, expected 15", err.Errors[1].Code) | ||
} | ||
if err.Errors[1].Message != "other-error" { | ||
t.Errorf("Got %q, expected other-error", err.Errors[1].Message) | ||
} | ||
}) | ||
|
||
t.Run("Invalid JSON", func(t *testing.T) { | ||
b := []byte("clearly not json") | ||
_, ok := errorReader(b).(ErrorResponse) | ||
|
||
if ok { | ||
// If the data b is not JSON, we expect a "generic" errorString | ||
// (from fmt.Errorf), but we somehow got our own ErrorResponse back. | ||
t.Fatalf("Got ErrorResponse, expected errorString") | ||
} | ||
}) | ||
} | ||
|
||
func TestErrorResponseError(t *testing.T) { | ||
err := ErrorResponse{ | ||
[]Error{ | ||
{ | ||
Code: 1, | ||
Message: "foo", | ||
}, | ||
{ | ||
Code: 2, | ||
Message: "bar", | ||
}, | ||
}, | ||
} | ||
|
||
expect := `code: 1, message: "foo"; code: 2, message: "bar"` | ||
if actual := err.Error(); actual != expect { | ||
t.Fatalf("Got %q, expected %q", actual, expect) | ||
} | ||
} |