"fmt"
"reflect"
- "git.fd.io/govpp.git/api"
"github.com/lunixbochs/struc"
+
+ "git.fd.io/govpp.git/api"
)
// MsgCodec provides encoding and decoding functionality of `api.Message` structs into/from
}
// EncodeMsg encodes provided `Message` structure into its binary-encoded data representation.
-func (*MsgCodec) EncodeMsg(msg api.Message, msgID uint16) ([]byte, error) {
+func (*MsgCodec) EncodeMsg(msg api.Message, msgID uint16) (data []byte, err error) {
if msg == nil {
return nil, errors.New("nil message passed in")
}
- // encode message header
+ // try to recover panic which might possibly occur in struc.Pack call
+ defer func() {
+ if r := recover(); r != nil {
+ var ok bool
+ if err, ok = r.(error); !ok {
+ err = fmt.Errorf("%v", r)
+ }
+ err = fmt.Errorf("panic occurred during encoding message %s: %v", msg.GetMessageName(), err)
+ }
+ }()
+
var header interface{}
+
+ // encode message header
switch msg.GetMessageType() {
case api.RequestMessage:
header = &VppRequestHeader{VlMsgID: msgID}
// encode message header
if err := struc.Pack(buf, header); err != nil {
- return nil, fmt.Errorf("unable to encode message header: %v, error %v", header, err)
+ return nil, fmt.Errorf("failed to encode message header: %+v, error: %v", header, err)
}
// encode message content
if reflect.TypeOf(msg).Elem().NumField() > 0 {
if err := struc.Pack(buf, msg); err != nil {
- return nil, fmt.Errorf("unable to encode message data: %v, error %v", header, err)
+ return nil, fmt.Errorf("failed to encode message data: %+v, error: %v", data, err)
}
}
}
// DecodeMsg decodes binary-encoded data of a message into provided `Message` structure.
-func (*MsgCodec) DecodeMsg(data []byte, msg api.Message) error {
+func (*MsgCodec) DecodeMsg(data []byte, msg api.Message) (err error) {
if msg == nil {
return errors.New("nil message passed in")
}
- // check which header is expected
+ // try to recover panic which might possibly occur
+ defer func() {
+ if r := recover(); r != nil {
+ var ok bool
+ if err, ok = r.(error); !ok {
+ err = fmt.Errorf("%v", r)
+ }
+ err = fmt.Errorf("panic occurred during decoding message %s: %v", msg.GetMessageName(), err)
+ }
+ }()
+
var header interface{}
+
+ // check which header is expected
switch msg.GetMessageType() {
case api.RequestMessage:
header = new(VppRequestHeader)
buf := bytes.NewReader(data)
// decode message header
- if err := struc.Unpack(buf, header); err != nil {
- return fmt.Errorf("unable to decode message header: %+v, error %v", data, err)
+ if err = struc.Unpack(buf, header); err != nil {
+ return fmt.Errorf("failed to decode message header: %+v, error: %v", header, err)
}
// decode message content
if err := struc.Unpack(buf, msg); err != nil {
- return fmt.Errorf("unable to decode message data: %+v, error %v", data, err)
+ return fmt.Errorf("failed to decode message data: %+v, error: %v", data, err)
}
return nil
return 0, errors.New("nil message passed in")
}
+ var header interface{}
var getContext func() uint32
// check which header is expected
- var header interface{}
switch msg.GetMessageType() {
case api.RequestMessage:
header = new(VppRequestHeader)
getContext = func() uint32 { return header.(*VppRequestHeader).Context }
+
case api.ReplyMessage:
header = new(VppReplyHeader)
getContext = func() uint32 { return header.(*VppReplyHeader).Context }
+
default:
return 0, nil
}