geektutu/7days-golang · error

h.Error

Error message

h.Error

What it means

In gee-rpc/day5-http-debug's receive loop, when the server reports a failure via the response header's Error field, the client sets call.Error = fmt.Errorf(h.Error) — the surfaced message is the server-side error string itself. Typical server messages are "rpc server: service X method Y not found" and "rpc server: failed to handle request: <panic or decode error>".

Source

Thrown at gee-rpc/day5-http-debug/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 the server's registration calls (geerpc.Register / RegisterName) and use the exact service and method names
  2. Ensure the method is exported (capitalized) with two exported pointer parameters and one error return
  3. Match the client args type to the server method's first parameter
  4. Inspect server logs for the original panic message if the error text shows a recovered panic

Example fix

// before
var reply string
err := client.Call("Foo/sum", req, &reply) // wrong separator/case
// after
err := client.Call("Foo.Sum", req, &reply) // matches srv.Register(new(Foo)) with exported Sum method
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling, ensure the server registered this method (client-side check is not possible;
// guard the method name string)
const method = "Foo.Sum" // must match server registration exactly, case-sensitive
if !strings.Contains(method, ".") { return errors.New("ServiceMethod must be \"Service.Method\"") }

Try / catch

err := client.Call("Foo.Sum", req, reply)
if err != nil {
	if strings.Contains(err.Error(), "not found") {
		// wrong service/method name: fix registration or name
	} else if strings.Contains(err.Error(), "failed to handle request") {
		// server panic or decode error: check server logs, verify arg types
	}
}

Prevention

When it happens

Trigger: Calling a ServiceMethod that is not registered on the server (wrong service or method name); arguments cannot be decoded on the server; the service method panics and the server recovers, writing the recovered error into h.Error.

Common situations: Typos or refactors in "Service.Method" names; client/server have different registrations (e.g. only DotoriService registered with prefix); exported-method requirement violated on the server; arg/reply type mismatch causing server decode failure; panic inside the handler.

Related errors


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