From cd6859b0744351d4cfc5d40fadcb804dbbcfdd85 Mon Sep 17 00:00:00 2001 From: Tyschitskaya Maria Date: Wed, 26 Jan 2022 14:35:38 +0300 Subject: [PATCH 1/5] add unmarshal error --- messenger.go | 2 +- response.go | 4 ++-- response_test.go | 14 +++++++++++ unmarshal_error.go | 46 ++++++++++++++++++++++++++++++++++++ unmarshal_error_test.go | 52 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 unmarshal_error.go create mode 100644 unmarshal_error_test.go 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) +} From f24f4d512e2fae214f8c366d30c88da5dff98096 Mon Sep 17 00:00:00 2001 From: Tyschitskaya Maria Date: Thu, 27 Jan 2022 14:56:47 +0300 Subject: [PATCH 2/5] ioutil in unmarshal error --- .github/workflows/ci.yml | 2 +- unmarshal_error.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ccd5d3f..9799a8c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go-version: ['1.11', '1.12', '1.13', '1.14', '1.15', '1.16', '1.17'] + go-version: ['1.13', '1.14', '1.15', '1.16', '1.17'] steps: - name: Set up Go ${{ matrix.go-version }} uses: actions/setup-go@v2 diff --git a/unmarshal_error.go b/unmarshal_error.go index ca6918d..1163f9c 100644 --- a/unmarshal_error.go +++ b/unmarshal_error.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "io/ioutil" ) var ErrUnmarshal = errors.New("unmarshal error") @@ -15,7 +16,7 @@ type UnmarshalError struct { } func (u *UnmarshalError) Error() string { - content, err := io.ReadAll(u.Content) + content, err := ioutil.ReadAll(u.Content) if err != nil { content = []byte("[can not read content]") } From c1e9fd594dd2306e803a23b0f7e0e26f704c437d Mon Sep 17 00:00:00 2001 From: Tyschitskaya Maria Date: Thu, 27 Jan 2022 17:17:20 +0300 Subject: [PATCH 3/5] buffer from decoder in unmarshal error --- response.go | 11 ++++++----- response_test.go | 6 ++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/response.go b/response.go index d5bca94..a7a0502 100644 --- a/response.go +++ b/response.go @@ -87,9 +87,10 @@ func checkFacebookError(r io.Reader) error { var err error qr := QueryResponse{} - err = json.NewDecoder(r).Decode(&qr) + decoder := json.NewDecoder(r) + err = decoder.Decode(&qr) if err != nil { - return NewUnmarshalError().WithReader(r) + return NewUnmarshalError().WithReader(decoder.Buffered()) } if qr.Error != nil { return xerrors.Errorf("facebook error: %w", qr.Error) @@ -100,9 +101,9 @@ func checkFacebookError(r io.Reader) error { func getFacebookQueryResponse(r io.Reader) (QueryResponse, error) { qr := QueryResponse{} - err := json.NewDecoder(r).Decode(&qr) - if err != nil { - return qr, NewUnmarshalError().WithReader(r) + decoder := json.NewDecoder(r) + if err := decoder.Decode(&qr); err != nil { + return qr, NewUnmarshalError().WithReader(decoder.Buffered()) } if qr.Error != nil { return qr, xerrors.Errorf("facebook error: %w", qr.Error) diff --git a/response_test.go b/response_test.go index f15663e..258b639 100644 --- a/response_test.go +++ b/response_test.go @@ -19,13 +19,15 @@ func Test_MarshalStructuredMessageElement(t *testing.T) { } func TestResponse_checkFacebookError_UnmarshalError(t *testing.T) { - r := bytes.NewReader([]byte("test")) + r := bytes.NewReader([]byte("test error text")) err := checkFacebookError(r) assert.True(t, errors.Is(err, ErrUnmarshal)) + assert.Contains(t, err.Error(), "test error text") } func TestResponse_getFacebookQueryResponse_UnmarshalError(t *testing.T) { - r := bytes.NewReader([]byte("test")) + r := bytes.NewReader([]byte("test error text")) _, err := getFacebookQueryResponse(r) assert.True(t, errors.Is(err, ErrUnmarshal)) + assert.Contains(t, err.Error(), "test error text") } From 76d0d601a0c335c5e8b6c2faa50b56446b51d448 Mon Sep 17 00:00:00 2001 From: Tyschitskaya Maria Date: Fri, 28 Jan 2022 12:24:58 +0300 Subject: [PATCH 4/5] unmarshal error text --- messenger.go | 2 +- response.go | 4 ++-- unmarshal_error.go | 27 +++++++++++++-------------- unmarshal_error_test.go | 33 +++++++++++++++++++-------------- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/messenger.go b/messenger.go index 4ef799f..7e574df 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, NewUnmarshalError().WithReaderContent(content) + return p, NewUnmarshalError(err).WithContent(content) } if p == *new(Profile) { diff --git a/response.go b/response.go index a7a0502..d2db26c 100644 --- a/response.go +++ b/response.go @@ -90,7 +90,7 @@ func checkFacebookError(r io.Reader) error { decoder := json.NewDecoder(r) err = decoder.Decode(&qr) if err != nil { - return NewUnmarshalError().WithReader(decoder.Buffered()) + return NewUnmarshalError(err).WithReader(decoder.Buffered()) } if qr.Error != nil { return xerrors.Errorf("facebook error: %w", qr.Error) @@ -103,7 +103,7 @@ func getFacebookQueryResponse(r io.Reader) (QueryResponse, error) { qr := QueryResponse{} decoder := json.NewDecoder(r) if err := decoder.Decode(&qr); err != nil { - return qr, NewUnmarshalError().WithReader(decoder.Buffered()) + return qr, NewUnmarshalError(err).WithReader(decoder.Buffered()) } if qr.Error != nil { return qr, xerrors.Errorf("facebook error: %w", qr.Error) diff --git a/unmarshal_error.go b/unmarshal_error.go index 1163f9c..ddcb816 100644 --- a/unmarshal_error.go +++ b/unmarshal_error.go @@ -1,43 +1,42 @@ package messenger import ( - "bytes" "errors" "fmt" "io" - "io/ioutil" ) var ErrUnmarshal = errors.New("unmarshal error") type UnmarshalError struct { - Content io.Reader - Err error + Content []byte + ErrorText string + Err error } func (u *UnmarshalError) Error() string { - content, err := ioutil.ReadAll(u.Content) - if err != nil { - content = []byte("[can not read content]") - } - return fmt.Sprintf("can not unmarshal content: %s", string(content)) + return fmt.Sprintf("can not unmarshal content: %s; error: %s", string(u.Content), u.ErrorText) } func (u *UnmarshalError) Unwrap() error { return u.Err } -func NewUnmarshalError() *UnmarshalError { - return &UnmarshalError{Err: ErrUnmarshal} +func NewUnmarshalError(err error) *UnmarshalError { + return &UnmarshalError{ + Err: ErrUnmarshal, + ErrorText: err.Error(), + } } -func (u *UnmarshalError) WithReader(content io.Reader) *UnmarshalError { +func (u *UnmarshalError) WithReader(reader io.Reader) *UnmarshalError { + content, _ := io.ReadAll(reader) u.Content = content return u } -func (u *UnmarshalError) WithReaderContent(content []byte) *UnmarshalError { - u.Content = bytes.NewReader(content) +func (u *UnmarshalError) WithContent(content []byte) *UnmarshalError { + u.Content = content return u } diff --git a/unmarshal_error_test.go b/unmarshal_error_test.go index 1d799df..f8e160c 100644 --- a/unmarshal_error_test.go +++ b/unmarshal_error_test.go @@ -9,44 +9,49 @@ import ( ) func TestNewUnmarshalError(t *testing.T) { - err := NewUnmarshalError() - assert.True(t, errors.Is(err, ErrUnmarshal)) + err := errors.New("some error") + unmarshalError := NewUnmarshalError(err) + assert.True(t, errors.Is(unmarshalError, ErrUnmarshal)) } func TestUnmarshalError_Error(t *testing.T) { + err := errors.New("some error") content := []byte("test content") - actual := NewUnmarshalError().WithReaderContent(content).Error() - expected := "can not unmarshal content: test content" + actual := NewUnmarshalError(err).WithContent(content).Error() + expected := "can not unmarshal content: test content; error: some error" assert.Equal(t, expected, actual) } func TestUnmarshalError_Unwrap(t *testing.T) { - actual := NewUnmarshalError().Unwrap() + err := errors.New("some error") + actual := NewUnmarshalError(err).Unwrap() expected := ErrUnmarshal assert.Equal(t, expected, actual) } -func TestUnmarshalError_WithReaderContent(t *testing.T) { +func TestUnmarshalError_WithContent(t *testing.T) { + err := errors.New("some error") content := []byte("test content") - reader := bytes.NewReader(content) - actual := NewUnmarshalError().WithReaderContent(content) - expected := &UnmarshalError{Err: ErrUnmarshal, Content: reader} + actual := NewUnmarshalError(err).WithContent(content) + expected := &UnmarshalError{Err: ErrUnmarshal, Content: content, ErrorText: err.Error()} assert.Equal(t, expected, actual) } func TestUnmarshalError_WithReader(t *testing.T) { + err := errors.New("some error") content := []byte("test content") reader := bytes.NewReader(content) - actual := NewUnmarshalError().WithReader(reader) - expected := &UnmarshalError{Err: ErrUnmarshal, Content: reader} + actual := NewUnmarshalError(err).WithReader(reader) + expected := &UnmarshalError{Err: ErrUnmarshal, Content: content, ErrorText: err.Error()} assert.Equal(t, expected, actual) } func TestUnmarshalError_WithErr(t *testing.T) { - err := errors.New("some error") - actual := NewUnmarshalError().WithErr(err) - expected := &UnmarshalError{Err: err} + someError := errors.New("some error") + otherError := errors.New("other error") + actual := NewUnmarshalError(someError).WithErr(otherError) + expected := &UnmarshalError{Err: otherError, ErrorText: someError.Error()} assert.Equal(t, expected, actual) } From d0069e73f870c30722050319ccbc888f57c712e2 Mon Sep 17 00:00:00 2001 From: Tyschitskaya Maria Date: Fri, 28 Jan 2022 12:28:24 +0300 Subject: [PATCH 5/5] json error text tests fix --- unmarshal_error.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unmarshal_error.go b/unmarshal_error.go index ddcb816..f782454 100644 --- a/unmarshal_error.go +++ b/unmarshal_error.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "io" + "io/ioutil" ) var ErrUnmarshal = errors.New("unmarshal error") @@ -30,7 +31,7 @@ func NewUnmarshalError(err error) *UnmarshalError { } func (u *UnmarshalError) WithReader(reader io.Reader) *UnmarshalError { - content, _ := io.ReadAll(reader) + content, _ := ioutil.ReadAll(reader) u.Content = content return u }