Skip to content

Commit

Permalink
fix batchOrder response and fix futures.WsUserDataEvent.Time error wh…
Browse files Browse the repository at this point in the history
…ile calling json.Unmarshal (#581)

* fix batchOrder response and fix futures.WsUserDataEvent.Time error while
json.Unmarshal

* also fix this in the delivery package
  • Loading branch information
xyq-c-cpp authored Jun 24, 2024
1 parent 130172e commit b3a9097
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 24 deletions.
38 changes: 38 additions & 0 deletions v2/delivery/websocket_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"strconv"
"strings"
"time"
)
Expand Down Expand Up @@ -671,6 +672,43 @@ type WsUserDataEvent struct {
OrderTradeUpdate WsOrderTradeUpdate `json:"o"`
}

func (e *WsUserDataEvent) UnmarshalJSON(data []byte) error {
var tmp struct {
Event UserDataEventType `json:"e"`
Time interface{} `json:"E"`
Alias string `json:"i"`
CrossWalletBalance string `json:"cw"`
MarginCallPositions []WsPosition `json:"p"`
TransactionTime int64 `json:"T"`
AccountUpdate WsAccountUpdate `json:"a"`
OrderTradeUpdate WsOrderTradeUpdate `json:"o"`
}
if err := json.Unmarshal(data, &tmp); err != nil {
return err
}

e.Event = tmp.Event
switch v := tmp.Time.(type) {
case float64:
e.Time = int64(v)
case string:
parsedTime, err := strconv.ParseInt(v, 10, 64)
if err != nil {
return err
}
e.Time = parsedTime
default:
return fmt.Errorf("unexpected type for E: %T", tmp.Time)
}
e.Alias = tmp.Alias
e.CrossWalletBalance = tmp.CrossWalletBalance
e.MarginCallPositions = tmp.MarginCallPositions
e.TransactionTime = tmp.TransactionTime
e.AccountUpdate = tmp.AccountUpdate
e.OrderTradeUpdate = tmp.OrderTradeUpdate
return nil
}

// WsAccountUpdate define account update
type WsAccountUpdate struct {
Reason UserDataEventReasonType `json:"m"`
Expand Down
38 changes: 38 additions & 0 deletions v2/futures/websocket_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"strconv"
"strings"
"time"
)
Expand Down Expand Up @@ -980,6 +981,43 @@ type WsUserDataEvent struct {
AccountConfigUpdate WsAccountConfigUpdate `json:"ac"`
}

func (e *WsUserDataEvent) UnmarshalJSON(data []byte) error {
var tmp struct {
Event UserDataEventType `json:"e"`
Time interface{} `json:"E"`
CrossWalletBalance string `json:"cw"`
MarginCallPositions []WsPosition `json:"p"`
TransactionTime int64 `json:"T"`
AccountUpdate WsAccountUpdate `json:"a"`
OrderTradeUpdate WsOrderTradeUpdate `json:"o"`
AccountConfigUpdate WsAccountConfigUpdate `json:"ac"`
}
if err := json.Unmarshal(data, &tmp); err != nil {
return err
}

e.Event = tmp.Event
switch v := tmp.Time.(type) {
case float64:
e.Time = int64(v)
case string:
parsedTime, err := strconv.ParseInt(v, 10, 64)
if err != nil {
return err
}
e.Time = parsedTime
default:
return fmt.Errorf("unexpected type for E: %T", tmp.Time)
}
e.CrossWalletBalance = tmp.CrossWalletBalance
e.MarginCallPositions = tmp.MarginCallPositions
e.TransactionTime = tmp.TransactionTime
e.AccountUpdate = tmp.AccountUpdate
e.OrderTradeUpdate = tmp.OrderTradeUpdate
e.AccountConfigUpdate = tmp.AccountConfigUpdate
return nil
}

// WsAccountUpdate define account update
type WsAccountUpdate struct {
Reason UserDataEventReasonType `json:"m"`
Expand Down
66 changes: 51 additions & 15 deletions v2/options/order_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"fmt"
"net/http"
"strings"

"github.com/adshao/go-binance/v2/common"
)

// CreateOrderService create order
Expand Down Expand Up @@ -435,8 +437,8 @@ func (s *CancelBatchOrdersService) ClientOrderIds(clientOrderIds []string) *Canc
return s
}

// Do send request
func (s *CancelBatchOrdersService) Do(ctx context.Context, opts ...RequestOption) (res []*Order, err error) {
// return: [Order, APIError]
func (s *CancelBatchOrdersService) Do(ctx context.Context, opts ...RequestOption) (res []interface{}, err error) {
r := &request{
method: http.MethodDelete,
endpoint: "/eapi/v1/batchOrders",
Expand All @@ -461,14 +463,30 @@ func (s *CancelBatchOrdersService) Do(ctx context.Context, opts ...RequestOption
}
rlos := header.Get("X-Mbx-Order-Count-10s")
rlom := header.Get("X-Mbx-Order-Count-1m")
res = make([]*Order, 0)
err = json.Unmarshal(data, &res)

rawMessages := make([]*json.RawMessage, 0)
err = json.Unmarshal(data, &rawMessages)
if err != nil {
return []*Order{}, err
return []interface{}{}, err
}
for idx := range res {
res[idx].RateLimitOrder10s = rlos
res[idx].RateLimitOrder1m = rlom

res = make([]interface{}, 0)
for _, j := range rawMessages {
e := new(common.APIError)
if err := json.Unmarshal(*j, e); err != nil {
return []interface{}{}, err
}
if e.IsValid() {
res = append(res, *e)
continue
}
o := new(Order)
if err := json.Unmarshal(*j, o); err != nil {
return []interface{}{}, err
}
o.RateLimitOrder10s = rlos
o.RateLimitOrder1m = rlom
res = append(res, *o)
}
return res, nil
}
Expand All @@ -483,7 +501,8 @@ func (s *CreateBatchOrdersService) OrderList(orders []*CreateOrderService) *Crea
return s
}

func (s *CreateBatchOrdersService) Do(ctx context.Context, opts ...RequestOption) (res []*Order, err error) {
// return: [Order, APIError]
func (s *CreateBatchOrdersService) Do(ctx context.Context, opts ...RequestOption) (res []interface{}, err error) {
r := &request{
method: http.MethodPost,
endpoint: "/eapi/v1/batchOrders",
Expand All @@ -494,7 +513,7 @@ func (s *CreateBatchOrdersService) Do(ctx context.Context, opts ...RequestOption
for _, order := range s.orders {
if order.newOrderRespType != "" && order.newOrderRespType != NewOrderRespTypeACK &&
order.newOrderRespType != NewOrderRespTypeRESULT {
return []*Order{}, fmt.Errorf("no expected newOrderRespType value=%v", order.newOrderRespType)
return []interface{}{}, fmt.Errorf("no expected newOrderRespType value=%v", order.newOrderRespType)
}
m := params{
"symbol": order.symbol,
Expand Down Expand Up @@ -525,9 +544,10 @@ func (s *CreateBatchOrdersService) Do(ctx context.Context, opts ...RequestOption
}
orders = append(orders, m)
}

b, err := json.Marshal(orders)
if err != nil {
return []*Order{}, err
return []interface{}{}, err
}
m := params{
"orders": string(b),
Expand All @@ -537,15 +557,31 @@ func (s *CreateBatchOrdersService) Do(ctx context.Context, opts ...RequestOption

data, _, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return []*Order{}, err
return []interface{}{}, err
}

res = make([]*Order, 0)
err = json.Unmarshal(data, &res)
rawMessages := make([]*json.RawMessage, 0)
err = json.Unmarshal(data, &rawMessages)
if err != nil {
return []*Order{}, err
return []interface{}{}, err
}

res = make([]interface{}, 0)
for _, j := range rawMessages {
e := new(common.APIError)
if err := json.Unmarshal(*j, e); err != nil {
return []interface{}{}, err
}
if e.IsValid() {
res = append(res, *e)
continue
}
o := new(Order)
if err := json.Unmarshal(*j, o); err != nil {
return []interface{}{}, err
}
res = append(res, *o)
}
return res, nil
}

Expand Down
51 changes: 42 additions & 9 deletions v2/options/order_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"testing"

"github.com/adshao/go-binance/v2/common"
"github.com/stretchr/testify/suite"
)

Expand Down Expand Up @@ -61,6 +62,22 @@ func (s *baseOrderTestSuite) assertOrdersEqual(e, a []*Order) {
}
}

func (s *baseOrderTestSuite) assertOrderAndAPIErrorListEqual(e, a []interface{}) {
for i := range e {
switch ee := e[i].(type) {
case Order:
aa, ok := a[i].(Order)
s.r().Equal(true, ok, "convert Order failed")
s.assertOrderEqual(&ee, &aa)
case common.APIError:
aa, ok := a[i].(common.APIError)
s.r().Equal(true, ok, "convert APIError failed")
s.r().Equal(ee.Code, aa.Code, "Code")
s.r().Equal(ee.Message, aa.Message, "Message")
}
}
}

func (s *orderServiceTestSuite) TestCreateOrder() {
data := []byte(`{
"orderId": 4729003411963445248,
Expand Down Expand Up @@ -200,6 +217,10 @@ func (s *orderServiceTestSuite) TestCreateBatchOrders() {
"optionSide": "CALL",
"quoteAsset": "USDT",
"mmp": false
},
{
"code": 1002,
"msg": "test 1002"
}
]`)
s.mockDo(data, nil)
Expand Down Expand Up @@ -284,10 +305,10 @@ func (s *orderServiceTestSuite) TestCreateBatchOrders() {
returnOrders, err := s.client.NewCreateBatchOrdersService().OrderList(orderLists).Do(newContext())
r := s.r()
r.NoError(err)
r.Len(returnOrders, 2)
r.Len(returnOrders, 3)

orders := []*Order{
{
orders := []interface{}{
Order{
OrderId: 4710989013445263360,
Symbol: "DOGE-240607-0.158-C",
Price: "4.2000",
Expand All @@ -311,7 +332,7 @@ func (s *orderServiceTestSuite) TestCreateBatchOrders() {
QuoteAsset: "USDT",
Mmp: false,
},
{
Order{
OrderId: 4710989013445263361,
Symbol: "DOGE-240607-0.158-C",
Price: "4.2000",
Expand All @@ -335,8 +356,12 @@ func (s *orderServiceTestSuite) TestCreateBatchOrders() {
QuoteAsset: "USDT",
Mmp: false,
},
common.APIError{
Code: 1002,
Message: "test 1002",
},
}
s.assertOrdersEqual(orders, returnOrders)
s.assertOrderAndAPIErrorListEqual(orders, returnOrders)
}

func (s *orderServiceTestSuite) TestGetOrder() {
Expand Down Expand Up @@ -530,6 +555,10 @@ func (s *orderServiceTestSuite) TestCancelBatchOrders() {
"optionSide": "CALL",
"quoteAsset": "USDT",
"mmp": false
},
{
"code": 1002,
"msg": "test 1002"
}
]`)
s.mockDo(data, nil)
Expand All @@ -556,8 +585,8 @@ func (s *orderServiceTestSuite) TestCancelBatchOrders() {
r := s.r()
r.NoError(err)

e := []*Order{
{
e := []interface{}{
Order{
OrderId: 4710989013445263361,
Symbol: "DOGE-240607-0.158-C",
Price: "4.2000",
Expand All @@ -581,7 +610,7 @@ func (s *orderServiceTestSuite) TestCancelBatchOrders() {
QuoteAsset: "USDT",
Mmp: false,
},
{
Order{
OrderId: 4710989013445263360,
Symbol: "DOGE-240607-0.158-C",
Price: "4.2000",
Expand All @@ -605,8 +634,12 @@ func (s *orderServiceTestSuite) TestCancelBatchOrders() {
QuoteAsset: "USDT",
Mmp: false,
},
common.APIError{
Code: 1002,
Message: "test 1002",
},
}
s.assertOrdersEqual(e, res)
s.assertOrderAndAPIErrorListEqual(e, res)
}

func (s *orderServiceTestSuite) TestCancelAllOpenOrders() {
Expand Down

0 comments on commit b3a9097

Please sign in to comment.