Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/rpc/jsonrpc: return error when reply not set #19588

Closed
SuperGod opened this issue Mar 17, 2017 · 9 comments
Closed

net/rpc/jsonrpc: return error when reply not set #19588

SuperGod opened this issue Mar 17, 2017 · 9 comments
Labels
FrozenDueToAge help wanted NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@SuperGod
Copy link

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.8 windows/amd64

What operating system and processor architecture are you using (go env)?

set GOARCH=amd64
set GOBIN=
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=D:\go;D:\code\analyzer
set GORACE=
set GOROOT=D:\devtool\go64
set GOTOOLDIR=D:\devtool\go64\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\msys64\tmp\go-build642962111=/tmp/go-build -gno-record-gcc-switches
set CXX=g++
set CGO_ENABLED=1
set PKG_CONFIG=pkg-config
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2

What did you do?

I use this code to use jsonrpc:

package main

import (
	"fmt"
	"log"
	"net"
	"net/rpc"
	"net/rpc/jsonrpc"
)

type Arith int

type Result int

func (t *Arith) Multiply(args int, result *Result) error {
	return nil
}

func (t *Arith) DoMap(args int, result *map[string]string) error {
	*result = map[string]string{}
	return nil
}

func (t *Arith) DoMap2(args int, result *map[string]string) error {
	return nil
}

func main() {
	go runServer()
	client, err := jsonrpc.Dial("tcp", fmt.Sprintf("127.0.0.1:9001"))
	if err != nil {
		log.Fatal(err.Error())
	}

	var reply Result
	err = client.Call("Arith.Multiply", 1, &reply)
	if err != nil {
		log.Fatal(err.Error())
	}
	fmt.Println("call Multiply success")
	var ret map[string]string
	err = client.Call("Arith.DoMap", 1, &ret)
	if err != nil {
		log.Fatal(err.Error())
	}
	fmt.Println("call DoMap success")
	err = client.Call("Arith.DoMap2", 1, &ret)
	if err != nil {
		log.Fatal(err.Error())
	}
	fmt.Println("call DoMap2 success")
}

func runServer() {
	arith := new(Arith)
	rpc.Register(arith)
	tcpAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:9001")
	if err != nil {
		fmt.Println("ResolveTCPAddr error:", tcpAddr, err.Error())
		return
	}

	listener, err := net.ListenTCP("tcp", tcpAddr)
	if err != nil {
		fmt.Println("listen tcp error:", tcpAddr, err.Error())
		return
	}

	for {
		conn, err := listener.Accept()
		if err != nil {
			continue
		}
		jsonrpc.ServeConn(conn)
	}
}

What did you expect to see?

I think "DoMap2" should return the same of "DoMap"

What did you see instead?

I use "go run client.go" to test the program,but the output is:

call Multiply success
call DoMap success
2017/03/17 18:15:03 invalid error <nil>
exit status 1

It seems “DoMap2” return an error, but "DoMap" and "Multiply" return no error

@bradfitz bradfitz changed the title jsonrpc return error when reply not set net/rpc/jsonrpc: return error when reply not set Mar 17, 2017
@bradfitz bradfitz added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Mar 17, 2017
@bradfitz bradfitz added this to the Go1.9 milestone Mar 17, 2017
@fraenkel
Copy link
Contributor

This is correct. JSON-RPC says the result must be non-null on success.
http://www.jsonrpc.org/specification#response_object
DoMap2 doesn't set the result hence a nil flows which is treated as an error.

@SuperGod
Copy link
Author

But why "Multiply" return no error? I did not set the result of "result *Result"

@fraenkel
Copy link
Contributor

Because result is not null. An *int is created with a value of 0.

@SuperGod
Copy link
Author

OK,thanks, I understand it.

But I think it can easily be confused .

@fraenkel
Copy link
Contributor

The part that might be considered a bug is that the map is not created. I would also wonder if slices have a similar issue given how the return value is created.

@bradfitz
Copy link
Contributor

For consistency with the *int result case, we should probably make nil maps be valid and treat them like empty maps. Everything else in Go works like that anyway.

I'd accept a patch.

@bradfitz bradfitz added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Mar 23, 2017
@bradfitz bradfitz modified the milestones: Go1.9Maybe, Go1.9 Mar 23, 2017
@SuperGod
Copy link
Author

I test slices,it have the same issue.

@fraenkel
Copy link
Contributor

@gopherbot
Copy link

CL https://golang.org/cl/38474 mentions this issue.

@golang golang locked and limited conversation to collaborators Mar 23, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge help wanted NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

4 participants