Skip to content

Commit b3a9097

Browse files
authored
fix batchOrder response and fix futures.WsUserDataEvent.Time error while calling json.Unmarshal (#581)
* fix batchOrder response and fix futures.WsUserDataEvent.Time error while json.Unmarshal * also fix this in the delivery package
1 parent 130172e commit b3a9097

File tree

4 files changed

+169
-24
lines changed

4 files changed

+169
-24
lines changed

v2/delivery/websocket_service.go

+38
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/json"
55
"errors"
66
"fmt"
7+
"strconv"
78
"strings"
89
"time"
910
)
@@ -671,6 +672,43 @@ type WsUserDataEvent struct {
671672
OrderTradeUpdate WsOrderTradeUpdate `json:"o"`
672673
}
673674

675+
func (e *WsUserDataEvent) UnmarshalJSON(data []byte) error {
676+
var tmp struct {
677+
Event UserDataEventType `json:"e"`
678+
Time interface{} `json:"E"`
679+
Alias string `json:"i"`
680+
CrossWalletBalance string `json:"cw"`
681+
MarginCallPositions []WsPosition `json:"p"`
682+
TransactionTime int64 `json:"T"`
683+
AccountUpdate WsAccountUpdate `json:"a"`
684+
OrderTradeUpdate WsOrderTradeUpdate `json:"o"`
685+
}
686+
if err := json.Unmarshal(data, &tmp); err != nil {
687+
return err
688+
}
689+
690+
e.Event = tmp.Event
691+
switch v := tmp.Time.(type) {
692+
case float64:
693+
e.Time = int64(v)
694+
case string:
695+
parsedTime, err := strconv.ParseInt(v, 10, 64)
696+
if err != nil {
697+
return err
698+
}
699+
e.Time = parsedTime
700+
default:
701+
return fmt.Errorf("unexpected type for E: %T", tmp.Time)
702+
}
703+
e.Alias = tmp.Alias
704+
e.CrossWalletBalance = tmp.CrossWalletBalance
705+
e.MarginCallPositions = tmp.MarginCallPositions
706+
e.TransactionTime = tmp.TransactionTime
707+
e.AccountUpdate = tmp.AccountUpdate
708+
e.OrderTradeUpdate = tmp.OrderTradeUpdate
709+
return nil
710+
}
711+
674712
// WsAccountUpdate define account update
675713
type WsAccountUpdate struct {
676714
Reason UserDataEventReasonType `json:"m"`

v2/futures/websocket_service.go

+38
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/json"
55
"errors"
66
"fmt"
7+
"strconv"
78
"strings"
89
"time"
910
)
@@ -980,6 +981,43 @@ type WsUserDataEvent struct {
980981
AccountConfigUpdate WsAccountConfigUpdate `json:"ac"`
981982
}
982983

984+
func (e *WsUserDataEvent) UnmarshalJSON(data []byte) error {
985+
var tmp struct {
986+
Event UserDataEventType `json:"e"`
987+
Time interface{} `json:"E"`
988+
CrossWalletBalance string `json:"cw"`
989+
MarginCallPositions []WsPosition `json:"p"`
990+
TransactionTime int64 `json:"T"`
991+
AccountUpdate WsAccountUpdate `json:"a"`
992+
OrderTradeUpdate WsOrderTradeUpdate `json:"o"`
993+
AccountConfigUpdate WsAccountConfigUpdate `json:"ac"`
994+
}
995+
if err := json.Unmarshal(data, &tmp); err != nil {
996+
return err
997+
}
998+
999+
e.Event = tmp.Event
1000+
switch v := tmp.Time.(type) {
1001+
case float64:
1002+
e.Time = int64(v)
1003+
case string:
1004+
parsedTime, err := strconv.ParseInt(v, 10, 64)
1005+
if err != nil {
1006+
return err
1007+
}
1008+
e.Time = parsedTime
1009+
default:
1010+
return fmt.Errorf("unexpected type for E: %T", tmp.Time)
1011+
}
1012+
e.CrossWalletBalance = tmp.CrossWalletBalance
1013+
e.MarginCallPositions = tmp.MarginCallPositions
1014+
e.TransactionTime = tmp.TransactionTime
1015+
e.AccountUpdate = tmp.AccountUpdate
1016+
e.OrderTradeUpdate = tmp.OrderTradeUpdate
1017+
e.AccountConfigUpdate = tmp.AccountConfigUpdate
1018+
return nil
1019+
}
1020+
9831021
// WsAccountUpdate define account update
9841022
type WsAccountUpdate struct {
9851023
Reason UserDataEventReasonType `json:"m"`

v2/options/order_service.go

+51-15
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"fmt"
77
"net/http"
88
"strings"
9+
10+
"github.com/adshao/go-binance/v2/common"
911
)
1012

1113
// CreateOrderService create order
@@ -435,8 +437,8 @@ func (s *CancelBatchOrdersService) ClientOrderIds(clientOrderIds []string) *Canc
435437
return s
436438
}
437439

438-
// Do send request
439-
func (s *CancelBatchOrdersService) Do(ctx context.Context, opts ...RequestOption) (res []*Order, err error) {
440+
// return: [Order, APIError]
441+
func (s *CancelBatchOrdersService) Do(ctx context.Context, opts ...RequestOption) (res []interface{}, err error) {
440442
r := &request{
441443
method: http.MethodDelete,
442444
endpoint: "/eapi/v1/batchOrders",
@@ -461,14 +463,30 @@ func (s *CancelBatchOrdersService) Do(ctx context.Context, opts ...RequestOption
461463
}
462464
rlos := header.Get("X-Mbx-Order-Count-10s")
463465
rlom := header.Get("X-Mbx-Order-Count-1m")
464-
res = make([]*Order, 0)
465-
err = json.Unmarshal(data, &res)
466+
467+
rawMessages := make([]*json.RawMessage, 0)
468+
err = json.Unmarshal(data, &rawMessages)
466469
if err != nil {
467-
return []*Order{}, err
470+
return []interface{}{}, err
468471
}
469-
for idx := range res {
470-
res[idx].RateLimitOrder10s = rlos
471-
res[idx].RateLimitOrder1m = rlom
472+
473+
res = make([]interface{}, 0)
474+
for _, j := range rawMessages {
475+
e := new(common.APIError)
476+
if err := json.Unmarshal(*j, e); err != nil {
477+
return []interface{}{}, err
478+
}
479+
if e.IsValid() {
480+
res = append(res, *e)
481+
continue
482+
}
483+
o := new(Order)
484+
if err := json.Unmarshal(*j, o); err != nil {
485+
return []interface{}{}, err
486+
}
487+
o.RateLimitOrder10s = rlos
488+
o.RateLimitOrder1m = rlom
489+
res = append(res, *o)
472490
}
473491
return res, nil
474492
}
@@ -483,7 +501,8 @@ func (s *CreateBatchOrdersService) OrderList(orders []*CreateOrderService) *Crea
483501
return s
484502
}
485503

486-
func (s *CreateBatchOrdersService) Do(ctx context.Context, opts ...RequestOption) (res []*Order, err error) {
504+
// return: [Order, APIError]
505+
func (s *CreateBatchOrdersService) Do(ctx context.Context, opts ...RequestOption) (res []interface{}, err error) {
487506
r := &request{
488507
method: http.MethodPost,
489508
endpoint: "/eapi/v1/batchOrders",
@@ -494,7 +513,7 @@ func (s *CreateBatchOrdersService) Do(ctx context.Context, opts ...RequestOption
494513
for _, order := range s.orders {
495514
if order.newOrderRespType != "" && order.newOrderRespType != NewOrderRespTypeACK &&
496515
order.newOrderRespType != NewOrderRespTypeRESULT {
497-
return []*Order{}, fmt.Errorf("no expected newOrderRespType value=%v", order.newOrderRespType)
516+
return []interface{}{}, fmt.Errorf("no expected newOrderRespType value=%v", order.newOrderRespType)
498517
}
499518
m := params{
500519
"symbol": order.symbol,
@@ -525,9 +544,10 @@ func (s *CreateBatchOrdersService) Do(ctx context.Context, opts ...RequestOption
525544
}
526545
orders = append(orders, m)
527546
}
547+
528548
b, err := json.Marshal(orders)
529549
if err != nil {
530-
return []*Order{}, err
550+
return []interface{}{}, err
531551
}
532552
m := params{
533553
"orders": string(b),
@@ -537,15 +557,31 @@ func (s *CreateBatchOrdersService) Do(ctx context.Context, opts ...RequestOption
537557

538558
data, _, err := s.c.callAPI(ctx, r, opts...)
539559
if err != nil {
540-
return []*Order{}, err
560+
return []interface{}{}, err
541561
}
542562

543-
res = make([]*Order, 0)
544-
err = json.Unmarshal(data, &res)
563+
rawMessages := make([]*json.RawMessage, 0)
564+
err = json.Unmarshal(data, &rawMessages)
545565
if err != nil {
546-
return []*Order{}, err
566+
return []interface{}{}, err
547567
}
548568

569+
res = make([]interface{}, 0)
570+
for _, j := range rawMessages {
571+
e := new(common.APIError)
572+
if err := json.Unmarshal(*j, e); err != nil {
573+
return []interface{}{}, err
574+
}
575+
if e.IsValid() {
576+
res = append(res, *e)
577+
continue
578+
}
579+
o := new(Order)
580+
if err := json.Unmarshal(*j, o); err != nil {
581+
return []interface{}{}, err
582+
}
583+
res = append(res, *o)
584+
}
549585
return res, nil
550586
}
551587

v2/options/order_service_test.go

+42-9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/json"
55
"testing"
66

7+
"github.com/adshao/go-binance/v2/common"
78
"github.com/stretchr/testify/suite"
89
)
910

@@ -61,6 +62,22 @@ func (s *baseOrderTestSuite) assertOrdersEqual(e, a []*Order) {
6162
}
6263
}
6364

65+
func (s *baseOrderTestSuite) assertOrderAndAPIErrorListEqual(e, a []interface{}) {
66+
for i := range e {
67+
switch ee := e[i].(type) {
68+
case Order:
69+
aa, ok := a[i].(Order)
70+
s.r().Equal(true, ok, "convert Order failed")
71+
s.assertOrderEqual(&ee, &aa)
72+
case common.APIError:
73+
aa, ok := a[i].(common.APIError)
74+
s.r().Equal(true, ok, "convert APIError failed")
75+
s.r().Equal(ee.Code, aa.Code, "Code")
76+
s.r().Equal(ee.Message, aa.Message, "Message")
77+
}
78+
}
79+
}
80+
6481
func (s *orderServiceTestSuite) TestCreateOrder() {
6582
data := []byte(`{
6683
"orderId": 4729003411963445248,
@@ -200,6 +217,10 @@ func (s *orderServiceTestSuite) TestCreateBatchOrders() {
200217
"optionSide": "CALL",
201218
"quoteAsset": "USDT",
202219
"mmp": false
220+
},
221+
{
222+
"code": 1002,
223+
"msg": "test 1002"
203224
}
204225
]`)
205226
s.mockDo(data, nil)
@@ -284,10 +305,10 @@ func (s *orderServiceTestSuite) TestCreateBatchOrders() {
284305
returnOrders, err := s.client.NewCreateBatchOrdersService().OrderList(orderLists).Do(newContext())
285306
r := s.r()
286307
r.NoError(err)
287-
r.Len(returnOrders, 2)
308+
r.Len(returnOrders, 3)
288309

289-
orders := []*Order{
290-
{
310+
orders := []interface{}{
311+
Order{
291312
OrderId: 4710989013445263360,
292313
Symbol: "DOGE-240607-0.158-C",
293314
Price: "4.2000",
@@ -311,7 +332,7 @@ func (s *orderServiceTestSuite) TestCreateBatchOrders() {
311332
QuoteAsset: "USDT",
312333
Mmp: false,
313334
},
314-
{
335+
Order{
315336
OrderId: 4710989013445263361,
316337
Symbol: "DOGE-240607-0.158-C",
317338
Price: "4.2000",
@@ -335,8 +356,12 @@ func (s *orderServiceTestSuite) TestCreateBatchOrders() {
335356
QuoteAsset: "USDT",
336357
Mmp: false,
337358
},
359+
common.APIError{
360+
Code: 1002,
361+
Message: "test 1002",
362+
},
338363
}
339-
s.assertOrdersEqual(orders, returnOrders)
364+
s.assertOrderAndAPIErrorListEqual(orders, returnOrders)
340365
}
341366

342367
func (s *orderServiceTestSuite) TestGetOrder() {
@@ -530,6 +555,10 @@ func (s *orderServiceTestSuite) TestCancelBatchOrders() {
530555
"optionSide": "CALL",
531556
"quoteAsset": "USDT",
532557
"mmp": false
558+
},
559+
{
560+
"code": 1002,
561+
"msg": "test 1002"
533562
}
534563
]`)
535564
s.mockDo(data, nil)
@@ -556,8 +585,8 @@ func (s *orderServiceTestSuite) TestCancelBatchOrders() {
556585
r := s.r()
557586
r.NoError(err)
558587

559-
e := []*Order{
560-
{
588+
e := []interface{}{
589+
Order{
561590
OrderId: 4710989013445263361,
562591
Symbol: "DOGE-240607-0.158-C",
563592
Price: "4.2000",
@@ -581,7 +610,7 @@ func (s *orderServiceTestSuite) TestCancelBatchOrders() {
581610
QuoteAsset: "USDT",
582611
Mmp: false,
583612
},
584-
{
613+
Order{
585614
OrderId: 4710989013445263360,
586615
Symbol: "DOGE-240607-0.158-C",
587616
Price: "4.2000",
@@ -605,8 +634,12 @@ func (s *orderServiceTestSuite) TestCancelBatchOrders() {
605634
QuoteAsset: "USDT",
606635
Mmp: false,
607636
},
637+
common.APIError{
638+
Code: 1002,
639+
Message: "test 1002",
640+
},
608641
}
609-
s.assertOrdersEqual(e, res)
642+
s.assertOrderAndAPIErrorListEqual(e, res)
610643
}
611644

612645
func (s *orderServiceTestSuite) TestCancelAllOpenOrders() {

0 commit comments

Comments
 (0)