{"record":{"id":"f88edebb2b3f90a5","repo":"geektutu/7days-golang","slug":"h-error-f88ede","errorCode":null,"errorMessage":"h.Error","messagePattern":"h\\.Error","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gee-rpc/day6-load-balance/client.go","lineNumber":151,"sourceCode":"\t\t}\n\t}\n}\n\nfunc (client *Client) receive() {\n\tvar err error\n\tfor err == nil {\n\t\tvar h codec.Header\n\t\tif err = client.cc.ReadHeader(&h); err != nil {\n\t\t\tbreak\n\t\t}\n\t\tcall := client.removeCall(h.Seq)\n\t\tswitch {\n\t\tcase call == nil:\n\t\t\t// it usually means that Write partially failed\n\t\t\t// and call was already removed.\n\t\t\terr = client.cc.ReadBody(nil)\n\t\tcase h.Error != \"\":\n\t\t\tcall.Error = fmt.Errorf(h.Error)\n\t\t\terr = client.cc.ReadBody(nil)\n\t\t\tcall.done()\n\t\tdefault:\n\t\t\terr = client.cc.ReadBody(call.Reply)\n\t\t\tif err != nil {\n\t\t\t\tcall.Error = errors.New(\"reading body \" + err.Error())\n\t\t\t}\n\t\t\tcall.done()\n\t\t}\n\t}\n\t// error occurs, so terminateCalls pending calls\n\tclient.terminateCalls(err)\n}\n\n// Go invokes the function asynchronously.\n// It returns the Call structure representing the invocation.\nfunc (client *Client) Go(serviceMethod string, args, reply interface{}, done chan *Call) *Call {\n\tif done == nil {","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-rpc/day6-load-balance/client.go#L133-L169","documentation":"During Client.receive, when the response header carries a non-empty Error field, the server-side handler returned an error for this call. The client copies h.Error into call.Error (wrapped via fmt.Errorf) and reads/discards the body. The message 'h.Error' in logs is the sentinel location; the actual text is whatever the server reported.","triggerScenarios":"Server handler returned an error or the method was not found/registered; server replied with an error header for the call, and the goroutine reading responses assigns it to call.Error.","commonSituations":"Calling a method not registered on the server (e.g. typo in serviceName.methodName after a refactor); handler returning errors due to bad arguments, unmarshal failures, or server-side panics recovered as errors.","solutions":["Check call.Error text (returned from Client.Call) — it is the server-side error message; fix the root cause there.","Verify the service and method names match what the server registered (Register/DefaultRegister).","Ensure the Reply type matches the server's return type so server-side decoding does not fail."],"exampleFix":"// before\nerr := client.Call(\"Foo.Sum\", args, reply) // server has no service Foo\n// after\nerr := client.Call(\"Arith.Sum\", args, reply) // matches registered service","handlingStrategy":"try-catch","validationCode":"// Verify the method exists server-side before calling:\n// srv.Register(new(Arith)) must have been called on the server","typeGuard":null,"tryCatchPattern":"err := client.Call(\"Arith.Sum\", args, reply)\nif err != nil {\n    // err wraps the server-side h.Error message; log and handle\n    log.Printf(\"rpc call failed: %v\", err)\n    // decide: retry, fall back, or propagate\n}","preventionTips":["Keep service/method name constants shared between client and server.","Log the full call.Error text — it is the server's error and names the root cause.","Make arg/reply types identical and gob-compatible on both ends.","Register handlers defensively so missing methods return clear 'method not found' errors."],"tags":["rpc","server-error","remote-call"],"backgroundTag":"rpc-server-returned-error","analyzedSha":"cf3644382101dc13e7fd92e8f5c66cabc51bcd3b","analyzedAt":"2026-09-03T18:31:24.087Z","contentChangedAt":"2026-09-03T18:31:24.087Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}