Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

panic: reflect: call of reflect.Value.Type on zero Value #3

Open
hocine opened this issue Feb 18, 2013 · 6 comments
Open

panic: reflect: call of reflect.Value.Type on zero Value #3

hocine opened this issue Feb 18, 2013 · 6 comments

Comments

@hocine
Copy link

hocine commented Feb 18, 2013

I'm getting this error and I'm not sure what's causing it or how to debug it.

panic: reflect: call of reflect.Value.Type on zero Value

I'm getting it when doing a Get or Put with a the entity type Service:

type Service struct {
    Date      time.Time
    Patient   int
    Dentist   *datastore.Key
    Procedure *datastore.Key
    Insurance *datastore.Key
    Created   time.Time
    Updated   time.Time
    Key       *datastore.Key
    Version   int
}

And, this is the code that's failing with cachestore. They both work fine with datastore.Get/Put, but fail with cachestore.

GETTING:

var (
    c     = appengine.NewContext(r)
    query = datastore.NewQuery("Service").Order("-Date").KeysOnly()
    keys  []*datastore.Key
)

if k != nil {
    s := fmt.Sprintf("%s =", k.Kind())
    query = query.Filter(s, k)
}

keys, err := query.GetAll(c, nil)
if err != nil {
    Log(r, 5, "There was an error querying the datastore for %v: %v", query, err)
    return nil
}

for _, k := range keys {
    x := new(Service)
    if err := cachestore.Get(c, k, x); err != nil {
        Log(r, 2, "Couldn't find service: %v", err)
    } else {
        Log(r, 1, "Service found: %v", x)

        if x.Key == nil {
            x.Key = k
        }
        services = append(services, *x)
    }
}
Log(r, 1, "Found %v services: %v", len(services), services)

PUTTING:

var (
    c    = appengine.NewContext(r)
    serv = new(Service)
    err  error
)

date := r.FormValue("date")
if serv.Date, err = validatedate(date); err != nil {
    Log(r, 1, "Date '%s' is not valid: %v", date, err)
    return
}
Log(r, 1, "String is valid: %v", date)

patient := r.FormValue("patient")
if serv.Patient, err = validatepatientid(patient); err != nil {
    Log(r, 1, "Patient ID '%s' is not valid: %v", patient, err)
    return
}
Log(r, 1, "Patient ID is valid: %v", patient)

dentist := r.FormValue("dentist")
if serv.Dentist, err = validatedentistid(c, dentist); err != nil {
    Log(r, 1, "Dentist ID '%s' is not valid: %v", dentist, err)
    return
}
Log(r, 1, "Dentist ID is valid: %v", dentist)

procedure := r.FormValue("procedure")
if serv.Procedure, err = validateprocedureid(c, procedure); err != nil {
    Log(r, 1, "Procedure ID '%s' is not valid: %v", procedure, err)
    return
}
Log(r, 1, "Procedure ID is valid: %v", procedure)

insurance := r.FormValue("insurance")
if serv.Insurance, err = validateinsuranceid(c, insurance); err != nil {
    Log(r, 1, "Insurance ID '%s' is not valid: %v", insurance, err)
    return
}
Log(r, 1, "Insurance ID is valid: %v", insurance)

k := datastore.NewIncompleteKey(c, "Service", nil)

serv.Created = time.Now()
serv.Updated = time.Now()
serv.Version = API_VERSION

if serv.Key, err = cachestore.Put(c, k, serv); err != nil {
    Log(r, 5, "An error occurred while adding the %v procedure to the datastore: %v", k, err)
    return
}
Log(r, 1, "Placed service in the datastore at %v: %v", serv.Key, serv)
@oschmid
Copy link
Owner

oschmid commented Feb 18, 2013

I'll take a look at it when I get home tonight. Thanks for reporting the issue.

@hocine
Copy link
Author

hocine commented Feb 18, 2013

No problem, thanks for responding so quickly! I'm sure I'm doing something wrong because it's working fine in my other app. I just don't know what it could be.

@oschmid
Copy link
Owner

oschmid commented Feb 19, 2013

That panic happens when the reflect.Value.Type() method is called on an zero value (i.e. uninitialized struct, nil, 0, empty string, etc). cachestore calls this method in checkMultiArg() (appengine.go : 54) on the reflected value of the destination (when decoding) or source (when encoding). This would be a *Service in your case. In which case I know exactly what's wrong, and it's my fault: cachestore doesn't work with pointer destinations or sources. I'll see what I can do to get that working. In the mean time, try Get/Pull with a Service rather than a *Service, that should work.

@hocine
Copy link
Author

hocine commented Feb 19, 2013

Oh, I thought it wanted pointers to empty structs. From the docs on cachestore.Get: ....it is recommended to pass either a pointer to a zero valued struct....

@oschmid
Copy link
Owner

oschmid commented Feb 19, 2013

Oops, that should say "either a pointer OR a zero valued struct" and since I haven't figured out how to get gob to nicely marshal/unmarshal with pointers (even though it should do that automatically according to the docs) it only works with zero valued structs.

@oschmid
Copy link
Owner

oschmid commented Feb 19, 2013

Updated the docs and the readme so people know about the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants