Hi, r/golang. I am new to goland and got a challenge to understand this golang client. After that, I need to implement the server to make this client actually work. Here is link to the code: https://play.golang.org/p/pCXTaCaQsn
Basically, I have finished implementing the server for the client after 3 days trying to understand the client. The response from the server would be: {"Init":0,"Add":0,"Normalize":0,"Dump":9000} for GET request and "HELLO" for POST request.
The problem is, the client exits at line 165. Is there anyway to make it run all the way to the end ? Am I missing something ?
评论:
ChristophBerger:
aragon0510:Line 156 logs an err value. What does the message say?
A tip for troubleshooting: There are some packages like spew or q that can help inspecting the actual values of variables during execution. Just put some spew.Dump(...) or q.Q(...) calls into the functions that return with an error (CallWithoutResult and Call) and you can see if there is something wrong with the data that these functions process.
This should get you quickly to the root cause.
ChristophBerger:Line 156: I believe if the GetIndex() returns it right, the err should be nil. Otherwise, it will log whatever err returned from GetIndex()
ChristophBerger:Apologies! I made a typo, I meant line 165 of course. (The one you mentioned as the line that errors out.)
Let's try breaking this down:
Line 165 executes if
CallWithoutResult
returns a non-nill error.
CallWithoutResult
receives an URL string and anAtom
(that implementsSerializer
). It returns the error value it gets fromCall
.
Call
takes over the parameters fromCallWithoutResult
and returns a non-nil error in two cases:
http.Post
returns an error, orhttp.Post
returns status code 300 or greater.
http.Post
receives an URL asstring
, a fixed string "application/octet-stream", and the result ofUnion(args)
of type io.Reader.args
is a slice of typeSerializer
(an interface).
Union
receives a slice ofSerializer
s, creates a pipe, and spawns a goroutine that iterates over the slice and writes the serialized values to the pipe.So the code ultimately enters line 165 if
http.Post
errors out for one of the two reasons mentioned above. No other parts of the scenario generate new errors.-> Find out which of the two reasons apply. The error message should tell whether
http.Post
returned an error or rather a status code >= 300.-> Inspect the data that http.Post receives. Check the values of
url
and ofargs
just beforehttp.Post
is invoked. These may give a hint about whyhttp.Post
errors out.
aragon0510:Just noticed something strange:
This
if CallWithoutResult(url, ops.Dump) == nil { os.Exit(1) }
will exit if CallWithoutResult returns NO error. It will continue to line 164 if there is an error.
Is this the intended behavior? Should this perhaps rather read
if ... != nil
?
ChristophBerger:I thought about that last night and tried to comment out the block in line 164 (supposed the http.post returned no error).
After I commented out the block in line 164, the code ran to line 197 => break and exit at 208.
I am thinking the json I send from the server is not right json.
aragon0510:Agreed, most probably the error is caused by wrong data.
ChristophBerger:{"Init":0,"Add":0,"Normalize":0,"Dump":9000}
this is what i came up. Mostly because Index has Atom type (which is int type) members
aragon0510:Is this the JSON that GetIndex receives?
ChristophBerger:Yes. I made a small server to send that json through the url
Ok, then the first CallWithoutResult gets ops.Dump, which is 9000, and the second one (that fails) gets ops.Init, which is 0. Looks like there is a problem when passing this 0 to http.Post (via Union()). I cannot tell from the code where the problem is; I guess it's on the server's end.
