diff --git a/json/client.go b/json/client.go index e0aae3b..51ec94f 100644 --- a/json/client.go +++ b/json/client.go @@ -66,5 +66,8 @@ func DecodeClientResponse(r io.Reader, reply interface{}) error { if c.Result == nil { return errors.New("result is null") } + if reply == nil { + return nil + } return json.Unmarshal(*c.Result, reply) } diff --git a/json/json_test.go b/json/json_test.go index b9e0d90..397d693 100644 --- a/json/json_test.go +++ b/json/json_test.go @@ -135,3 +135,20 @@ func TestServiceBeforeAfter(t *testing.T) { t.Errorf("Expected after in context to be 'After is true', got %s", afterValue) } } + +func TestDecodeClientResponseNilReply(t *testing.T) { + ok := `{"id":1,"result":{"Result":8},"error":null}` + if err := DecodeClientResponse(bytes.NewReader([]byte(ok)), nil); err != nil { + t.Error("Expected nil reply to skip result unmarshal, got:", err) + } + + rpcErr := `{"id":1,"result":null,"error":"response error"}` + if err := DecodeClientResponse(bytes.NewReader([]byte(rpcErr)), nil); err == nil { + t.Error("Expected RPC error even when reply is nil") + } + + nullRes := `{"id":1,"result":null,"error":null}` + if err := DecodeClientResponse(bytes.NewReader([]byte(nullRes)), nil); err == nil { + t.Error("Expected error for null result even when reply is nil") + } +} diff --git a/v2/json2/client.go b/v2/json2/client.go index 729deb2..759a2b1 100644 --- a/v2/json2/client.go +++ b/v2/json2/client.go @@ -79,5 +79,9 @@ func DecodeClientResponse(r io.Reader, reply interface{}) error { return ErrNullResult } + if reply == nil { + return nil + } + return json.Unmarshal(*c.Result, reply) } diff --git a/v2/json2/json_test.go b/v2/json2/json_test.go index 23a19a8..3ce8a82 100644 --- a/v2/json2/json_test.go +++ b/v2/json2/json_test.go @@ -289,3 +289,24 @@ func TestDecodeNullResult(t *testing.T) { t.Error("Expected result to be nil, but got:", result) } } + +func TestDecodeClientResponseNilReply(t *testing.T) { + ok := `{"jsonrpc":"2.0","id":1,"result":{"Result":8}}` + if err := DecodeClientResponse(bytes.NewReader([]byte(ok)), nil); err != nil { + t.Error("Expected nil reply to skip result unmarshal, got:", err) + } + + rpcErr := `{"jsonrpc":"2.0","id":1,"error":{"code":-32000,"message":"response error"}}` + if err := DecodeClientResponse(bytes.NewReader([]byte(rpcErr)), nil); err == nil { + t.Error("Expected RPC error even when reply is nil") + } else if jsonRpcErr, ok := err.(*Error); !ok { + t.Errorf("Expected *Error, got %T: %s", err, err) + } else if jsonRpcErr.Message != "response error" { + t.Errorf("Expected message %q, got %q", "response error", jsonRpcErr.Message) + } + + nullRes := `{"jsonrpc":"2.0","id":1,"result":null}` + if err := DecodeClientResponse(bytes.NewReader([]byte(nullRes)), nil); err != ErrNullResult { + t.Error("Expected ErrNullResult for null result even when reply is nil, got:", err) + } +}