Skip to content

Commit 30f5a78

Browse files
committed
fix response decoding
1 parent 6a64aa5 commit 30f5a78

File tree

9 files changed

+170
-166
lines changed

9 files changed

+170
-166
lines changed

client/accounts_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import (
44
"errors"
55
"testing"
66

7+
"github.com/CreatureDev/xrpl-go/model/client/account"
8+
"github.com/CreatureDev/xrpl-go/model/client/common"
79
"github.com/mitchellh/mapstructure"
810
"github.com/stretchr/testify/mock"
911
"github.com/stretchr/testify/require"
10-
"github.com/CreatureDev/xrpl-go/model/client/account"
11-
"github.com/CreatureDev/xrpl-go/model/client/common"
1212
)
1313

1414
type mockClient struct {
@@ -19,6 +19,10 @@ type mockClientXrplResponse struct {
1919
Result map[string]any
2020
}
2121

22+
func (m *mockClientXrplResponse) GetError() error {
23+
return nil
24+
}
25+
2226
func (m *mockClientXrplResponse) GetResult(v any) error {
2327
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{TagName: "json", Result: &v})
2428
if err != nil {

client/client.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type XRPLRequest interface {
1616

1717
type XRPLResponse interface {
1818
GetResult(v any) error
19+
GetError() error
1920
}
2021

2122
type XRPLResponseWarning struct {

client/jsonrpc/jsonrpc_client.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import (
1111
"strings"
1212
"time"
1313

14-
jsoniter "github.com/json-iterator/go"
1514
"github.com/CreatureDev/xrpl-go/client"
1615
jsonrpcmodels "github.com/CreatureDev/xrpl-go/client/jsonrpc/models"
16+
jsoniter "github.com/json-iterator/go"
1717
)
1818

1919
type JsonRpcClient struct {
@@ -52,6 +52,7 @@ func (c *JsonRpcClient) SendRequest(reqParams client.XRPLRequest) (client.XRPLRe
5252
}
5353

5454
body, err := CreateRequest(reqParams)
55+
fmt.Printf("sending request: %s\n", string(body))
5556
if err != nil {
5657
return nil, err
5758
}
@@ -180,8 +181,8 @@ func CheckForError(res *http.Response) (jsonrpcmodels.JsonRpcResponse, error) {
180181
}
181182

182183
// result will have 'error' if error response
183-
if _, ok := jr.Result["error"]; ok {
184-
return jr, &JsonRpcClientError{ErrorString: jr.Result["error"].(string)}
184+
if err := jr.GetError(); err != nil {
185+
return jr, &JsonRpcClientError{ErrorString: err.Error()}
185186
}
186187

187188
return jr, nil

client/jsonrpc/jsonrpc_client_test.go

Lines changed: 76 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ import (
99
"testing"
1010
"time"
1111

12-
jsoniter "github.com/json-iterator/go"
13-
"github.com/stretchr/testify/assert"
1412
"github.com/CreatureDev/xrpl-go/client"
1513
jsonrpcmodels "github.com/CreatureDev/xrpl-go/client/jsonrpc/models"
1614
"github.com/CreatureDev/xrpl-go/model/client/account"
1715
"github.com/CreatureDev/xrpl-go/model/client/common"
1816
"github.com/CreatureDev/xrpl-go/model/client/utility"
17+
jsoniter "github.com/json-iterator/go"
18+
"github.com/stretchr/testify/assert"
1919
)
2020

2121
func TestJsonRpcClientCreation(t *testing.T) {
@@ -78,26 +78,26 @@ func TestCheckForError(t *testing.T) {
7878
t.Run("No error Response", func(t *testing.T) {
7979

8080
json := `{
81-
"result": {
82-
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
83-
"channels": [
84-
{
85-
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
86-
"amount": "1000",
87-
"balance": "0",
88-
"channel_id": "C7F634794B79DB40E87179A9D1BF05D05797AE7E92DF8E93FD6656E8C4BE3AE7",
89-
"destination_account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
90-
"public_key": "aBR7mdD75Ycs8DRhMgQ4EMUEmBArF8SEh1hfjrT2V9DQTLNbJVqw",
91-
"public_key_hex": "03CFD18E689434F032A4E84C63E2A3A6472D684EAF4FD52CA67742F3E24BAE81B2",
92-
"settle_delay": 60
93-
}
94-
],
95-
"ledger_hash": "27F530E5C93ED5C13994812787C1ED073C822BAEC7597964608F2C049C2ACD2D",
96-
"ledger_index": 71766343,
97-
"status": "success",
98-
"validated": true
81+
"result": {
82+
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
83+
"channels": [
84+
{
85+
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
86+
"amount": "1000",
87+
"balance": "0",
88+
"channel_id": "C7F634794B79DB40E87179A9D1BF05D05797AE7E92DF8E93FD6656E8C4BE3AE7",
89+
"destination_account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
90+
"public_key": "aBR7mdD75Ycs8DRhMgQ4EMUEmBArF8SEh1hfjrT2V9DQTLNbJVqw",
91+
"public_key_hex": "03CFD18E689434F032A4E84C63E2A3A6472D684EAF4FD52CA67742F3E24BAE81B2",
92+
"settle_delay": 60
9993
}
100-
}`
94+
],
95+
"ledger_hash": "27F530E5C93ED5C13994812787C1ED073C822BAEC7597964608F2C049C2ACD2D",
96+
"ledger_index": 71766343,
97+
"status": "success",
98+
"validated": true
99+
}
100+
}`
101101

102102
b := io.NopCloser(bytes.NewReader([]byte(json)))
103103
res := &http.Response{
@@ -210,31 +210,31 @@ func TestSendRequest(t *testing.T) {
210210
}
211211

212212
response := `{
213-
"result": {
214-
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
215-
"channels": [
216-
{
217-
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
218-
"amount": "1000",
219-
"balance": "0",
220-
"channel_id": "C7F634794B79DB40E87179A9D1BF05D05797AE7E92DF8E93FD6656E8C4BE3AE7",
221-
"destination_account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
222-
"public_key": "aBR7mdD75Ycs8DRhMgQ4EMUEmBArF8SEh1hfjrT2V9DQTLNbJVqw",
223-
"public_key_hex": "03CFD18E689434F032A4E84C63E2A3A6472D684EAF4FD52CA67742F3E24BAE81B2",
224-
"settle_delay": 60
225-
}
226-
],
227-
"ledger_hash": "1EDBBA3C793863366DF5B31C2174B6B5E6DF6DB89A7212B86838489148E2A581",
228-
"ledger_index": 71766314,
229-
"validated": true
230-
},
231-
"warning": "none",
232-
"warnings":
233-
[{
234-
"id": 1,
235-
"message": "message"
236-
}]
237-
}`
213+
"result": {
214+
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
215+
"channels": [
216+
{
217+
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
218+
"amount": "1000",
219+
"balance": "0",
220+
"channel_id": "C7F634794B79DB40E87179A9D1BF05D05797AE7E92DF8E93FD6656E8C4BE3AE7",
221+
"destination_account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
222+
"public_key": "aBR7mdD75Ycs8DRhMgQ4EMUEmBArF8SEh1hfjrT2V9DQTLNbJVqw",
223+
"public_key_hex": "03CFD18E689434F032A4E84C63E2A3A6472D684EAF4FD52CA67742F3E24BAE81B2",
224+
"settle_delay": 60
225+
}
226+
],
227+
"ledger_hash": "1EDBBA3C793863366DF5B31C2174B6B5E6DF6DB89A7212B86838489148E2A581",
228+
"ledger_index": 71766314,
229+
"validated": true
230+
},
231+
"warning": "none",
232+
"warnings":
233+
[{
234+
"id": 1,
235+
"message": "message"
236+
}]
237+
}`
238238

239239
mc := &mockClient{}
240240
mc.DoFunc = mockResponse(response, 200, mc)
@@ -247,24 +247,24 @@ func TestSendRequest(t *testing.T) {
247247
xrplResponse, err := jsonRpcClient.SendRequest(req)
248248

249249
expectedXrplResponse := &jsonrpcmodels.JsonRpcResponse{
250-
Result: jsonrpcmodels.AnyJson{
250+
Result: json.RawMessage(`{
251+
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
252+
"channels": [
253+
{
251254
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
252-
"channels": []any{
253-
map[string]any{
254-
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
255-
"amount": "1000",
256-
"balance": "0",
257-
"channel_id": "C7F634794B79DB40E87179A9D1BF05D05797AE7E92DF8E93FD6656E8C4BE3AE7",
258-
"destination_account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
259-
"public_key": "aBR7mdD75Ycs8DRhMgQ4EMUEmBArF8SEh1hfjrT2V9DQTLNbJVqw",
260-
"public_key_hex": "03CFD18E689434F032A4E84C63E2A3A6472D684EAF4FD52CA67742F3E24BAE81B2",
261-
"settle_delay": json.Number("60"),
262-
},
263-
},
264-
"ledger_hash": "1EDBBA3C793863366DF5B31C2174B6B5E6DF6DB89A7212B86838489148E2A581",
265-
"ledger_index": json.Number("71766314"),
266-
"validated": true,
267-
},
255+
"amount": "1000",
256+
"balance": "0",
257+
"channel_id": "C7F634794B79DB40E87179A9D1BF05D05797AE7E92DF8E93FD6656E8C4BE3AE7",
258+
"destination_account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
259+
"public_key": "aBR7mdD75Ycs8DRhMgQ4EMUEmBArF8SEh1hfjrT2V9DQTLNbJVqw",
260+
"public_key_hex": "03CFD18E689434F032A4E84C63E2A3A6472D684EAF4FD52CA67742F3E24BAE81B2",
261+
"settle_delay": 60
262+
}
263+
],
264+
"ledger_hash": "1EDBBA3C793863366DF5B31C2174B6B5E6DF6DB89A7212B86838489148E2A581",
265+
"ledger_index": 71766314,
266+
"validated": true
267+
}`),
268268
Warning: "none",
269269
Warnings: []client.XRPLResponseWarning{{
270270
Id: 1,
@@ -284,6 +284,8 @@ func TestSendRequest(t *testing.T) {
284284

285285
assert.NoError(t, err)
286286

287+
res := xrplResponse.(*jsonrpcmodels.JsonRpcResponse)
288+
assert.Equal(t, string(expectedXrplResponse.Result), string(res.Result))
287289
assert.Equal(t, expectedXrplResponse, xrplResponse)
288290

289291
assert.Equal(t, expected.Account, channelsResponse.Account)
@@ -297,17 +299,17 @@ func TestSendRequest(t *testing.T) {
297299
Account: "rLHmBn4fT92w4F6ViyYbjoizLTo83tHTHu",
298300
}
299301
response := `{
300-
"result": {
301-
"error": "ledgerIndexMalformed",
302-
"request": {
303-
"account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
304-
"command": "account_info",
305-
"ledger_index": "-",
306-
"strict": true
307-
},
308-
"status": "error"
309-
}
310-
}`
302+
"result": {
303+
"error": "ledgerIndexMalformed",
304+
"request": {
305+
"account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
306+
"command": "account_info",
307+
"ledger_index": "-",
308+
"strict": true
309+
},
310+
"status": "error"
311+
}
312+
}`
311313

312314
mc := &mockClient{}
313315
mc.DoFunc = mockResponse(response, 200, mc)
Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,50 @@
11
package jsonrpcmodels
22

33
import (
4-
"github.com/mitchellh/mapstructure"
4+
"encoding/json"
5+
"fmt"
6+
57
"github.com/CreatureDev/xrpl-go/client"
68
)
79

810
type JsonRpcResponse struct {
9-
Result AnyJson `json:"result"`
11+
Result json.RawMessage `json:"result"`
1012
Warning string `json:"warning,omitempty"`
1113
Warnings []client.XRPLResponseWarning `json:"warnings,omitempty"`
1214
Forwarded bool `json:"forwarded,omitempty"`
1315
}
1416

15-
type AnyJson map[string]interface{}
16-
1717
type ApiWarning struct {
1818
Id int `json:"id"`
1919
Message string `json:"message"`
2020
Details interface{} `json:"details,omitempty"`
2121
}
2222

2323
func (r JsonRpcResponse) GetResult(v any) error {
24-
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{TagName: "json",
25-
Result: &v, DecodeHook: mapstructure.TextUnmarshallerHookFunc()})
26-
24+
if len(r.Result) == 0 {
25+
return nil
26+
}
27+
err := json.Unmarshal(r.Result, v)
2728
if err != nil {
2829
return err
2930
}
30-
err = dec.Decode(r.Result)
31+
return nil
32+
}
33+
34+
func (r JsonRpcResponse) GetError() error {
35+
if len(r.Result) == 0 {
36+
return nil
37+
}
38+
type reqError struct {
39+
Error string `json:"error"`
40+
}
41+
var errResponse reqError
42+
err := json.Unmarshal(r.Result, &errResponse)
3143
if err != nil {
3244
return err
3345
}
46+
if errResponse.Error != "" {
47+
return fmt.Errorf(errResponse.Error)
48+
}
3449
return nil
3550
}

client/jsonrpc/models/jsonrpc_response_test.go

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,22 @@ package jsonrpcmodels
22

33
import (
44
"encoding/json"
5-
"strconv"
65
"testing"
76

8-
"github.com/stretchr/testify/assert"
97
"github.com/CreatureDev/xrpl-go/client"
108
"github.com/CreatureDev/xrpl-go/model/client/account"
9+
"github.com/stretchr/testify/assert"
1110
)
1211

1312
func TestGetResult(t *testing.T) {
1413
t.Run("correctly decodes", func(t *testing.T) {
1514

1615
jr := JsonRpcResponse{
17-
Result: AnyJson{
18-
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
19-
"ledger_hash": "27F530E5C93ED5C13994812787C1ED073C822BAEC7597964608F2C049C2ACD2D",
20-
"ledger_index": json.Number(strconv.FormatInt(71766343, 10)),
21-
},
16+
Result: json.RawMessage(`{
17+
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
18+
"ledger_hash": "27F530E5C93ED5C13994812787C1ED073C822BAEC7597964608F2C049C2ACD2D",
19+
"ledger_index": 71766343
20+
}`),
2221
Warning: "none",
2322
Warnings: []client.XRPLResponseWarning{{
2423
Id: 1,
@@ -42,11 +41,11 @@ func TestGetResult(t *testing.T) {
4241
t.Run("throws error for incorrect mapping", func(t *testing.T) {
4342

4443
jr := JsonRpcResponse{
45-
Result: AnyJson{
46-
"account": 123,
47-
"ledger_hash": "27F530E5C93ED5C13994812787C1ED073C822BAEC7597964608F2C049C2ACD2D",
48-
"ledger_index": json.Number(strconv.FormatInt(71766343, 10)),
49-
},
44+
Result: json.RawMessage(`{
45+
"account": 123,
46+
"ledger_hash": "27F530E5C93ED5C13994812787C1ED073C822BAEC7597964608F2C049C2ACD2D",
47+
"ledger_index": json.Number(strconv.FormatInt(71766343, 10)),
48+
}`),
5049
Warning: "none",
5150
Warnings: []client.XRPLResponseWarning{{
5251
Id: 1,

client/websocket/websocket_client.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import (
66
"errors"
77
"sync/atomic"
88

9-
"github.com/gorilla/websocket"
109
"github.com/CreatureDev/xrpl-go/client"
10+
"github.com/gorilla/websocket"
1111
)
1212

1313
var _ client.Client = (*WebsocketClient)(nil)
@@ -62,7 +62,7 @@ func (c *WebsocketClient) SendRequest(req client.XRPLRequest) (client.XRPLRespon
6262
if res.ID != int(id) {
6363
return nil, ErrIncorrectId
6464
}
65-
if err := res.CheckError(); err != nil {
65+
if err := res.GetError(); err != nil {
6666
return nil, err
6767
}
6868

0 commit comments

Comments
 (0)