From 64d0b93a7a1e85d58d11ac38c9404af80018f239 Mon Sep 17 00:00:00 2001 From: Quinn Slack Date: Sun, 22 Jan 2017 16:05:00 -0800 Subject: [PATCH] propagate JSON "null" result instead of treating it as Go nil (and field-not-present in JSON) --- jsonrpc2.go | 15 +++++++++++++-- object_test.go | 5 +++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/jsonrpc2.go b/jsonrpc2.go index c7724ac..7b921f3 100644 --- a/jsonrpc2.go +++ b/jsonrpc2.go @@ -377,7 +377,10 @@ func (c *Conn) Call(ctx context.Context, method string, params, result interface if err != nil { return err } - if result != nil && call.response.Result != nil { + if result != nil { + if call.response.Result == nil { + call.response.Result = &jsonNull + } // TODO(sqs): error handling if err := json.Unmarshal(*call.response.Result, result); err != nil { return err @@ -390,6 +393,8 @@ func (c *Conn) Call(ctx context.Context, method string, params, result interface } } +var jsonNull = json.RawMessage("null") + // Notify is like Call, but it returns when the notification request // is sent (without waiting for a response, because JSON-RPC // notifications do not have responses). @@ -595,7 +600,13 @@ func (m *anyMessage) UnmarshalJSON(data []byte) error { case !isRequest && isResponse: v = &m.response } - return json.Unmarshal(data, v) + if err := json.Unmarshal(data, v); err != nil { + return err + } + if !isRequest && isResponse && m.response.Error == nil && m.response.Result == nil { + m.response.Result = &jsonNull + } + return nil } // anyValueWithExplicitNull is used to distinguish {} from diff --git a/object_test.go b/object_test.go index c614712..906d99b 100644 --- a/object_test.go +++ b/object_test.go @@ -36,6 +36,7 @@ func TestAnyMessage(t *testing.T) { } func TestMessageCodec(t *testing.T) { + obj := json.RawMessage(`{"foo":"bar"}`) tests := []struct { v, vempty interface{} }{ @@ -44,8 +45,8 @@ func TestMessageCodec(t *testing.T) { vempty: &Request{ID: ID{Num: 123}}, }, { - v: &Response{ID: ID{Num: 123}}, - vempty: &Response{ID: ID{Num: 123}}, + v: &Response{ID: ID{Num: 123}, Result: &obj}, + vempty: &Response{ID: ID{Num: 123}, Result: &obj}, }, } for _, test := range tests {