2

I keep getting this error when I run my Go code which makes queries to my local postgres database.

Error:

panic serving [::1]:56708: runtime error: invalid memory address or nil pointer dereference
goroutine 23 [running]:
net/http.func·011()
    /usr/local/go/src/pkg/net/http/server.go:1100 +0xb7
runtime.panic(0x2ef0a0, 0x4d8ee4)
    /usr/local/go/src/pkg/runtime/panic.c:248 +0x18d
database/sql.(*DB).conn(0x0, 0x277a1, 0x0, 0x0)
    /usr/local/go/src/pkg/database/sql/sql.go:625 +0x751
database/sql.(*DB).Ping(0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/database/sql/sql.go:452 +0x39
main.firstHandler(0x58e9a8, 0xc208052320, 0xc2080284e0)
    /Users/Tommy/Documents/gocode/server/server.go:122 +0x35
net/http.HandlerFunc.ServeHTTP(0x3c6be8, 0x58e9a8, 0xc208052320, 0xc2080284e0)
    /usr/local/go/src/pkg/net/http/server.go:1235 +0x40
github.com/gorilla/mux.(*Router).ServeHTTP(0xc2080186e0, 0x58e9a8, 0xc208052320, 0xc2080284e0)
    /Users/Audrey/gocode/src/github.com/gorilla/mux/mux.go:98 +0x292
net/http.(*ServeMux).ServeHTTP(0xc208022660, 0x58e9a8, 0xc208052320, 0xc2080284e0)
    /usr/local/go/src/pkg/net/http/server.go:1511 +0x1a3
net/http.serverHandler.ServeHTTP(0xc208004660, 0x58e9a8, 0xc208052320, 0xc2080284e0)
    /usr/local/go/src/pkg/net/http/server.go:1673 +0x19f
net/http.(*conn).serve(0xc208050500)
    /usr/local/go/src/pkg/net/http/server.go:1174 +0xa7e
created by net/http.(*Server).Serve
    /usr/local/go/src/pkg/net/http/server.go:1721 +0x313

Go:

func firstHandler(w http.ResponseWriter, r *http.Request) {
    err := db.Ping()
    if err != nil {
        log.Fatal(err)
    }
    rows, err := db.Query("SELECT id, created_at, updated_at FROM script WHERE updated_at = $1", 3)
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    var created_at, updated_at, id int
    for rows.Next() {
        err := rows.Scan(&id, &created_at, &updated_at)
        if err != nil {
            log.Fatal(err)   
        }
       fmt.Fprintf("%s %s %s", id, created_at, updated_at)
    }
}

var r = mux.NewRouter()
var db *sql.DB

func main() {
    db, err := sql.Open("postgres", "user=Tommy host=localhost dbname=dbgo sslmode=verify-full")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    r.HandleFunc("/ping", firstHandler)

    http.Handle("/", r)

    http.ListenAndServe(":8080", nil)
}

Help. What am I doing wrong? I referred to this also: https://gophercasts.io/lessons/4-postgres-basics.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
user3918985
  • 4,278
  • 9
  • 42
  • 63

1 Answers1

15

Actually, you declare the connection with:

var db *sql.DB

but you open the connection with:

db, err := sql.Open("postgres", "user=Tommy host=localhost dbname=dbgo sslmode=verify-full")

Note the := (it combines a variable declaration with an assignment). This will actually shadow the global db variable by a local one. The connection is opened but assigned to the local variable. So the value of the global db variable is nil.

When the firstHandler function is called, its value is still nil, which triggers the panic.

Replace the := by a = (and declare the err object before).

Didier Spezia
  • 70,911
  • 12
  • 189
  • 154