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
Post a Comment