geektutu/7days-golang · error

reading body

Error message

reading body 

What it means

In receive(), the response header parsed OK but reading the reply body into call.Reply failed, so the call is failed with "reading body " + err.Error(). Typically the connection broke mid-response or the body doesn't fit/match the expected type.

Source

Thrown at gee-rpc/day2-client/client.go:152

	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 {
		done = make(chan *Call, 10)
	} else if cap(done) == 0 {
		log.Panic("rpc client: done channel is unbuffered")
	}
	call := &Call{
		ServiceMethod: serviceMethod,

View on GitHub (pinned to cf36443821)

Solutions

  1. Retry the call on a fresh connection (the client terminates pending calls on this error)
  2. Register reply types with gob.Register on both sides if decode errors appear after "reading body " Ensure Reply is a non-nil pointer to the correct struct
  3. Check server logs for panics/truncation during response write

Example fix

// before
call := client.Go("Foo.Sum", args, nil, nil).Done // nil reply -> body read fails
// after
reply := new(FooSumReply)
call := client.Go("Foo.Sum", args, reply, nil).Done
Defensive patterns

Strategy: retry

Validate before calling

if reflect.ValueOf(reply).Kind() != reflect.Ptr || reflect.ValueOf(reply).IsNil() {
    return errors.New("reply must be a non-nil pointer")
}

Try / catch

if err := client.Call(method, args, reply); err != nil {
    if strings.HasPrefix(err.Error(), "reading body ") {
        // decode/transport issue: re-dial and retry once; check gob registration
        return retryOnFreshConn(method, args, reply)
    }
    return err
}

Prevention

When it happens

Trigger: Server closes the connection after writing the header; network reset/EOF mid-body; codec cannot decode the body into call.Reply (type mismatch, wrong gob type registration); server crashed mid-response.

Common situations: Server panics while writing a large response; reply struct not gob.Register()ed causing decode errors; idle connections killed by a load balancer; passing a nil or wrong-typed Reply pointer.

Related errors


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