You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2017/01/18 00:52:00 UTC
[3/3] qpid-proton git commit: NO-JIRA: Clean up marshal/unmarshal
error handling
NO-JIRA: Clean up marshal/unmarshal error handling
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/eafd0810
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/eafd0810
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/eafd0810
Branch: refs/heads/master
Commit: eafd08104e232c911686b05f419a3c970706a554
Parents: 0f156d7
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Jan 17 16:16:23 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Jan 17 19:43:58 2017 -0500
----------------------------------------------------------------------
.../go/src/qpid.apache.org/amqp/marshal.go | 41 ++++++++++++-----
.../go/src/qpid.apache.org/amqp/unmarshal.go | 46 ++++++++++++--------
2 files changed, 59 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/eafd0810/proton-c/bindings/go/src/qpid.apache.org/amqp/marshal.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/marshal.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/marshal.go
index e3d4e10..b6adf90 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/amqp/marshal.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/marshal.go
@@ -29,12 +29,25 @@ import (
"unsafe"
)
-func dataError(prefix string, data *C.pn_data_t) error {
- err := PnError(C.pn_data_error(data))
- if err != nil {
- err = fmt.Errorf("%s: %s", prefix, err.Error())
+// Error returned if Go data cannot be marshaled as an AMQP type.
+type MarshalError struct {
+ // The Go type.
+ GoType reflect.Type
+ s string
+}
+
+func (e MarshalError) Error() string { return e.s }
+
+func newMarshalError(v interface{}, s string) *MarshalError {
+ t := reflect.TypeOf(v)
+ return &MarshalError{GoType: t, s: fmt.Sprintf("cannot marshal %s: %s", t, s)}
+}
+
+func dataMarshalError(v interface{}, data *C.pn_data_t) error {
+ if pe := PnError(C.pn_data_error(data)); pe != nil {
+ return newMarshalError(v, pe.Error())
}
- return err
+ return nil
}
/*
@@ -87,7 +100,16 @@ Described types.
*/
func Marshal(v interface{}, buffer []byte) (outbuf []byte, err error) {
- defer doRecover(&err)
+ defer func() {
+ if r := recover(); r != nil {
+ if merr, ok := r.(*MarshalError); ok {
+ err = merr
+ } else {
+ panic(r)
+ }
+ }
+ }()
+
data := C.pn_data(0)
defer C.pn_data_free(data)
marshal(v, data)
@@ -97,7 +119,7 @@ func Marshal(v interface{}, buffer []byte) (outbuf []byte, err error) {
case n == int(C.PN_OVERFLOW):
return buf, overflow
case n < 0:
- return buf, dataError("marshal error", data)
+ return buf, dataMarshalError(v, data)
default:
return buf[:n], nil
}
@@ -189,11 +211,10 @@ func marshal(v interface{}, data *C.pn_data_t) {
case reflect.Slice:
putList(data, v)
default:
- panic(fmt.Errorf("cannot marshal %s to AMQP", reflect.TypeOf(v)))
+ panic(newMarshalError(v, "no conversion"))
}
}
- err := dataError("marshal", data)
- if err != nil {
+ if err := dataMarshalError(v, data); err != nil {
panic(err)
}
return
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/eafd0810/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go
index 9b9cfd3..d56cbd2 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go
@@ -38,28 +38,39 @@ type UnmarshalError struct {
AMQPType string
// The Go type.
GoType reflect.Type
-}
-func newUnmarshalError(pnType C.pn_type_t, v interface{}) *UnmarshalError {
- return &UnmarshalError{C.pn_type_t(pnType).String(), reflect.TypeOf(v)}
+ s string
}
-func (e UnmarshalError) Error() string {
+func (e UnmarshalError) Error() string { return e.s }
+
+func newUnmarshalError(pnType C.pn_type_t, v interface{}) *UnmarshalError {
+ e := &UnmarshalError{AMQPType: C.pn_type_t(pnType).String(), GoType: reflect.TypeOf(v)}
if e.GoType.Kind() != reflect.Ptr {
- return fmt.Sprintf("cannot unmarshal to type %s, not a pointer", e.GoType)
+ e.s = fmt.Sprintf("cannot unmarshal to type %s, not a pointer", e.GoType)
} else {
- return fmt.Sprintf("cannot unmarshal AMQP %s to %s", e.AMQPType, e.GoType)
+ e.s = fmt.Sprintf("cannot unmarshal AMQP %s to %s", e.AMQPType, e.GoType)
}
+ return e
}
-func doRecover(err *error) {
- r := recover()
- switch r := r.(type) {
- case nil:
- case *UnmarshalError:
- *err = r
- default:
- panic(r)
+func newUnmarshalErrorData(data *C.pn_data_t, v interface{}) *UnmarshalError {
+ err := PnError(C.pn_data_error(data))
+ if err == nil {
+ return nil
+ }
+ e := newUnmarshalError(C.pn_data_type(data), v)
+ e.s = e.s + ": " + err.Error()
+ return e
+}
+
+func recoverUnmarshal(err *error) {
+ if r := recover(); r != nil {
+ if uerr, ok := r.(*UnmarshalError); ok {
+ *err = uerr
+ } else {
+ panic(r)
+ }
}
}
@@ -99,7 +110,7 @@ func (d *Decoder) Buffered() io.Reader {
// See the documentation for Unmarshal for details about the conversion of AMQP into a Go value.
//
func (d *Decoder) Decode(v interface{}) (err error) {
- defer doRecover(&err)
+ defer recoverUnmarshal(&err)
data := C.pn_data(0)
defer C.pn_data_free(data)
var n int
@@ -181,7 +192,7 @@ AMQP maps with mixed/unhashable key types need an alternate representation.
Described types.
*/
func Unmarshal(bytes []byte, v interface{}) (n int, err error) {
- defer doRecover(&err)
+ defer recoverUnmarshal(&err)
data := C.pn_data(0)
defer C.pn_data_free(data)
@@ -433,8 +444,7 @@ func unmarshal(v interface{}, data *C.pn_data_t) {
panic(newUnmarshalError(pnType, v))
}
}
- err := dataError("unmarshaling", data)
- if err != nil {
+ if err := newUnmarshalErrorData(data, v); err != nil {
panic(err)
}
return
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org