go - Why does gorm db.First() panic with "invalid memory address or nil pointer dereference"? -


i can't figure out if i've done silly or if i've found bug in gorm. while i'm aware of "invalid memory address or nil pointer dereference" means, mystified why appears here.

in short, call db.first() , receive panic no obvious reason.

the relevant bits of code:

package main  import (     "fmt"     "github.com/gorilla/mux"     "github.com/jinzhu/gorm"     "net/http"     "os" )  type message struct {     gorm.model     title string     body  string `sql:"size:0"` // blob }  var db = gorm.db{} // garbage  func messagehandler(w http.responsewriter, r *http.request) {     vars := mux.vars(r)     m := message{}     query := db.first(&m, vars["id"])     if query.error != nil {         if query.error == gorm.recordnotfound {             notfoundhandler(w, r)             return         } else {             fmt.fprintf(os.stderr, "database query failed: %v", query.error)             internalservererrorhandler(w, r)             return         }     }      // useful }  func main() {     db, err := gorm.open("sqlite3", "/tmp/gorm.db")     // ... } 

db opened in main() in package, , stored package variable. doesn't seem clean, appears work...

the panic:

2015/07/16 20:56:12 http: panic serving [::1]:37326: runtime error: invalid memory address or nil pointer dereference goroutine 26 [running]: net/http.func·011()         /usr/lib/golang/src/net/http/server.go:1130 +0xbb github.com/jinzhu/gorm.(*db).first(0xd28720, 0x79f220, 0xc2080b2600, 0xc2080ef220, 0x1, 0x1, 0xd)         /home/error/go/src/github.com/jinzhu/gorm/main.go:200 +0x154 main.messagehandler(0x7f4f2e785bd8, 0xc208051c20, 0xc208035790)         /home/error/go/src/myproject/messages.go:28 +0x2c1 net/http.handlerfunc.servehttp(0x9c3948, 0x7f4f2e785bd8, 0xc208051c20, 0xc208035790)         /usr/lib/golang/src/net/http/server.go:1265 +0x41 github.com/gorilla/mux.(*router).servehttp(0xc2080d9630, 0x7f4f2e785bd8, 0xc208051c20, 0xc208035790)         /home/error/go/src/github.com/gorilla/mux/mux.go:98 +0x297 net/http.serverhandler.servehttp(0xc2080890e0, 0x7f4f2e785bd8, 0xc208051c20, 0xc208035790)         /usr/lib/golang/src/net/http/server.go:1703 +0x19a net/http.(*conn).serve(0xc208051b80)         /usr/lib/golang/src/net/http/server.go:1204 +0xb57 created net/http.(*server).serve         /usr/lib/golang/src/net/http/server.go:1751 +0x35e 

...where line 28 of code query := db.first(&m, vars["id"])

i reviewed the noted line in gorm , first() function, isn't terribly obvious.

    return newscope.set("gorm:order_by_primary_key", "asc").         inlinecondition(where...).callcallbacks(s.parent.callback.queries).db 

in order figure out might going on, made following changes code:

first attempt: complaining being passed string? let's give integer instead. after all, example uses integer.

    id, _ := strconv.atoi(vars["id"])     query := db.first(&m, id) 

panic again, @ same place.

second attempt: did create variable m wrong way? maybe needs allocated new first.

    m := new(message)     query := db.first(m, vars["id"]) 

panic again, @ same place.

third attempt: hardcoded id looked up, in case gorilla/mux misbehaving.

    m := message{}     query := db.first(&m, 3) 

panic again, @ same place.

finally, tested empty database table, populated table requesting id exists, , populated table requesting id not exist. in 3 cases receive same panic.

the interesting part of apparently net/http recovering panic, , notfoundhandler() runs , see template output in browser.

i using mattn/go-sqlite3 driver.

my environment fedora 22 x86_64 cgo 1.4.2 provided in fedora rpm packages.

$ go version go version go1.4.2 linux/amd64  $ go env goarch="amd64" gobin="" gochar="6" goexe="" gohostarch="amd64" gohostos="linux" goos="linux" gopath="/home/error/go" gorace="" goroot="/usr/lib/golang" gotooldir="/usr/lib/golang/pkg/tool/linux_amd64" cc="gcc" gogccflags="-fpic -m64 -pthread -fmessage-length=0" cxx="g++" cgo_enabled="1" 

what's going on? panic coming from? how fix it?

you're shadowing global db variable:

var db = gorm.db{} // garbage 

your initialisation in main() should changed to:

var err error // note assignment , not initialise + assign operator db, err = gorm.open("sqlite3", "/tmp/gorm.db") 

otherwise, db nil , results in panic.


Comments

Popular posts from this blog

c# - Better 64-bit byte array hash -

webrtc - Which ICE candidate am I using and why? -

php - Zend Framework / Skeleton-Application / Composer install issue -