diff --git a/messenger.go b/messenger.go index bc23cba..4ef799f 100644 --- a/messenger.go +++ b/messenger.go @@ -198,7 +198,7 @@ func (m *Messenger) ProfileByID(id int64, profileFields []string) (Profile, erro err = json.Unmarshal(content, &p) if err != nil { - return p, err + return p, NewUnmarshalError().WithReaderContent(content) } if p == *new(Profile) { diff --git a/response.go b/response.go index a606f4f..d5bca94 100644 --- a/response.go +++ b/response.go @@ -89,7 +89,7 @@ func checkFacebookError(r io.Reader) error { qr := QueryResponse{} err = json.NewDecoder(r).Decode(&qr) if err != nil { - return xerrors.Errorf("json unmarshal error: %w", err) + return NewUnmarshalError().WithReader(r) } if qr.Error != nil { return xerrors.Errorf("facebook error: %w", qr.Error) @@ -102,7 +102,7 @@ func getFacebookQueryResponse(r io.Reader) (QueryResponse, error) { qr := QueryResponse{} err := json.NewDecoder(r).Decode(&qr) if err != nil { - return qr, xerrors.Errorf("json unmarshal error: %w", err) + return qr, NewUnmarshalError().WithReader(r) } if qr.Error != nil { return qr, xerrors.Errorf("facebook error: %w", qr.Error) diff --git a/response_test.go b/response_test.go index cd0a26a..f15663e 100644 --- a/response_test.go +++ b/response_test.go @@ -1,7 +1,9 @@ package messenger import ( + "bytes" "encoding/json" + "errors" "testing" "github.com/stretchr/testify/assert" @@ -15,3 +17,15 @@ func Test_MarshalStructuredMessageElement(t *testing.T) { require.NoError(t, err) assert.JSONEq(t, string(data), `{"image_url":"", "subtitle":"", "title": "Title"}`) } + +func TestResponse_checkFacebookError_UnmarshalError(t *testing.T) { + r := bytes.NewReader([]byte("test")) + err := checkFacebookError(r) + assert.True(t, errors.Is(err, ErrUnmarshal)) +} + +func TestResponse_getFacebookQueryResponse_UnmarshalError(t *testing.T) { + r := bytes.NewReader([]byte("test")) + _, err := getFacebookQueryResponse(r) + assert.True(t, errors.Is(err, ErrUnmarshal)) +} diff --git a/unmarshal_error.go b/unmarshal_error.go new file mode 100644 index 0000000..ca6918d --- /dev/null +++ b/unmarshal_error.go @@ -0,0 +1,46 @@ +package messenger + +import ( + "bytes" + "errors" + "fmt" + "io" +) + +var ErrUnmarshal = errors.New("unmarshal error") + +type UnmarshalError struct { + Content io.Reader + Err error +} + +func (u *UnmarshalError) Error() string { + content, err := io.ReadAll(u.Content) + if err != nil { + content = []byte("[can not read content]") + } + return fmt.Sprintf("can not unmarshal content: %s", string(content)) +} + +func (u *UnmarshalError) Unwrap() error { + return u.Err +} + +func NewUnmarshalError() *UnmarshalError { + return &UnmarshalError{Err: ErrUnmarshal} +} + +func (u *UnmarshalError) WithReader(content io.Reader) *UnmarshalError { + u.Content = content + return u +} + +func (u *UnmarshalError) WithReaderContent(content []byte) *UnmarshalError { + u.Content = bytes.NewReader(content) + return u +} + +func (u *UnmarshalError) WithErr(err error) *UnmarshalError { + u.Err = err + return u +} diff --git a/unmarshal_error_test.go b/unmarshal_error_test.go new file mode 100644 index 0000000..1d799df --- /dev/null +++ b/unmarshal_error_test.go @@ -0,0 +1,52 @@ +package messenger + +import ( + "bytes" + "errors" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewUnmarshalError(t *testing.T) { + err := NewUnmarshalError() + assert.True(t, errors.Is(err, ErrUnmarshal)) +} + +func TestUnmarshalError_Error(t *testing.T) { + content := []byte("test content") + actual := NewUnmarshalError().WithReaderContent(content).Error() + expected := "can not unmarshal content: test content" + assert.Equal(t, expected, actual) +} + +func TestUnmarshalError_Unwrap(t *testing.T) { + actual := NewUnmarshalError().Unwrap() + expected := ErrUnmarshal + assert.Equal(t, expected, actual) +} + +func TestUnmarshalError_WithReaderContent(t *testing.T) { + content := []byte("test content") + reader := bytes.NewReader(content) + + actual := NewUnmarshalError().WithReaderContent(content) + expected := &UnmarshalError{Err: ErrUnmarshal, Content: reader} + assert.Equal(t, expected, actual) +} + +func TestUnmarshalError_WithReader(t *testing.T) { + content := []byte("test content") + reader := bytes.NewReader(content) + + actual := NewUnmarshalError().WithReader(reader) + expected := &UnmarshalError{Err: ErrUnmarshal, Content: reader} + assert.Equal(t, expected, actual) +} + +func TestUnmarshalError_WithErr(t *testing.T) { + err := errors.New("some error") + actual := NewUnmarshalError().WithErr(err) + expected := &UnmarshalError{Err: err} + assert.Equal(t, expected, actual) +}