json/call.go
func (c *Client) Call(ctx Context, method string, arg, resp interface{}) error {
	var (
		headers = ctx.Headers()

		respHeaders map[string]string
		respErr     ErrApplication
		errAt       string
		isOK        bool
	)

	err := c.ch.RunWithRetry(ctx, func(ctx context.Context, rs *tchannel.RequestState) error {
		respHeaders, respErr, isOK = nil, nil, false
		errAt = "connect"

		call, err := c.startCall(ctx, method, &tchannel.CallOptions{
			Format:       tchannel.JSON,
			RequestState: rs,
		})
		if err != nil {
			return err
		}

		isOK, errAt, err = makeCall(call, headers, arg, &respHeaders, resp, &respErr)
		return err
	})
	if err != nil {
		// TODO: Don't lose the error type here.
		return fmt.Errorf("%s: %v", errAt, err)
	}
	if !isOK {
		return respErr
	}

	return nil
}
func (c *Client) Call(ctx Context, method string, arg, resp interface{}) error {
	var (
		headers = ctx.Headers()

		respHeaders map[string]string
		respErr     ErrApplication
		errAt       string
		isOK        bool
	)

	err := c.ch.RunWithRetry(ctx, func(ctx context.Context, rs *tchannel.RequestState) error {
		respHeaders, respErr, isOK = nil, nil, false
		errAt = "connect"

		call, err := c.startCall(ctx, method, &tchannel.CallOptions{
			Format:       tchannel.JSON,
			RequestState: rs,
		})
		if err != nil {
			return err
		}

		isOK, errAt, err = makeCall(call, headers, arg, &respHeaders, resp, &respErr)
		return err
	})
	if err != nil {
		// TODO: Don't lose the error type here.
		return fmt.Errorf("%s: %v", errAt, err)
	}
	if !isOK {
		return respErr
	}

	return nil
}
// Call makes a JSON call, with retries.