geektutu/7days-golang · error

h.Error

Error message

h.Error

What it means

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.

Source

Thrown at gee-rpc/day6-load-balance/client.go:151

		}
	}
}

func (client *Client) receive() {
	var err error
	for err == nil {
		var h codec.Header
		if err = client.cc.ReadHeader(&h); err != nil {
			break
		}
		call := client.removeCall(h.Seq)
		switch {
		case call == nil:
			// it usually means that Write partially failed
			// and call was already removed.
			err = client.cc.ReadBody(nil)
		case h.Error != "":
			call.Error = fmt.Errorf(h.Error)
			err = client.cc.ReadBody(nil)
			call.done()
		default:
			err = client.cc.ReadBody(call.Reply)
			if err != nil {
				call.Error = errors.New("reading body " + err.Error())
			}
			call.done()
		}
	}
	// error occurs, so terminateCalls pending calls
	client.terminateCalls(err)
}

// Go invokes the function asynchronously.
// It returns the Call structure representing the invocation.
func (client *Client) Go(serviceMethod string, args, reply interface{}, done chan *Call) *Call {
	if done == nil {

View on GitHub (pinned to cf36443821)

Solutions

  1. Check call.Error text (returned from Client.Call) — it is the server-side error message; fix the root cause there.
  2. Verify the service and method names match what the server registered (Register/DefaultRegister).
  3. Ensure the Reply type matches the server's return type so server-side decoding does not fail.

Example fix

// before
err := client.Call("Foo.Sum", args, reply) // server has no service Foo
// after
err := client.Call("Arith.Sum", args, reply) // matches registered service
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the method exists server-side before calling:
// srv.Register(new(Arith)) must have been called on the server

Try / catch

err := client.Call("Arith.Sum", args, reply)
if err != nil {
    // err wraps the server-side h.Error message; log and handle
    log.Printf("rpc call failed: %v", err)
    // decide: retry, fall back, or propagate
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03). Data as JSON: /api/errors/f88edebb2b3f90a5. Report an issue: GitHub.