duandu1049
2017-05-18 05:05
浏览 80

Golang-将数据插入MySQL DB时流意外结束

I'm currently writing a code in Golang that handles POST requests and store data into the MySQL database.

Here's what I've written so far.

package main

import (
    "fmt"
    "os"
    "log"
    "net/http"
    "database/sql"
    "golang.org/x/crypto/bcrypt"
    _ "github.com/go-sql-driver/mysql"
)

var myLogger *log.Logger
var db *sql.DB
var err error

type UserRegistrationData struct {
    email string
    password string
}

func handler(w http.ResponseWriter, r *http.Request) {
    myLogger = log.New(os.Stdout, "INFO: ", log.LstdFlags)

    var email string = r.PostFormValue("email")
    var password string = r.PostFormValue("password")

    data := UserRegistrationData{email, password}
    jsonEncoded, _ := json.Marshal(data)

    myLogger.Println("Success")

    hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
    _, err = db.Exec("INSERT INTO users (email, password) VALUES (?, ?)", email, hashedPassword)
}

func initialiseDB() {
    db, err := sql.Open("mysql", "root:@/authenticationgolang")

    if err != nil {
        panic(err.Error())
    }

    defer db.Close()
}

func main() {
    initialiseDB()
    http.HandleFunc("/call", handler)
    http.ListenAndServe(":8080", nil)
}

As I run the code and try to save the data, I keep getting the following message.

unexpected end of stream on Connection{10.10.10.153:8080, proxy=DIRECT@hostAddress=/10.10.10.153:8080 cipherSuite=none protocol=http/1.1}

The log seems to point out that this line has a problem, and I would like to ask somebody for fixing this out.

_, err = db.Exec("INSERT INTO users (email, password) VALUES (?, ?)", email, hashedPassword)

Added Here's the log message I get on the console.

2017/05/18 14:47:52 http: panic serving 10.10.10.58:41668: runtime error: invalid memory address or nil pointer dereference
goroutine 20 [running]:
net/http.(*conn).serve.func1(0xc4201360a0)
    /usr/local/Cellar/go/1.8.1/libexec/src/net/http/server.go:1721 +0xd0
panic(0x1288b60, 0x1424e70)
    /usr/local/Cellar/go/1.8.1/libexec/src/runtime/panic.go:489 +0x2cf
database/sql.(*DB).conn(0x0, 0x14027c0, 0xc420010450, 0xc420034801, 0x10000000142ec80, 0x1600960, 0x2)
    /usr/local/Cellar/go/1.8.1/libexec/src/database/sql/sql.go:896 +0x3a
database/sql.(*DB).exec(0x0, 0x14027c0, 0xc420010450, 0x12e699d, 0x31, 0xc420045c58, 0x2, 0x2, 0x1, 0x0, ...)
    /usr/local/Cellar/go/1.8.1/libexec/src/database/sql/sql.go:1183 +0xb9
database/sql.(*DB).ExecContext(0x0, 0x14027c0, 0xc420010450, 0x12e699d, 0x31, 0xc420045c58, 0x2, 0x2, 0x126ed20, 0xc42013c440, ...)
    /usr/local/Cellar/go/1.8.1/libexec/src/database/sql/sql.go:1165 +0xbc
database/sql.(*DB).Exec(0x0, 0x12e699d, 0x31, 0xc420034c58, 0x2, 0x2, 0x3c, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.8.1/libexec/src/database/sql/sql.go:1179 +0x85
main.handler(0x14022c0, 0xc42014a0e0, 0xc420144100)
    /Users/marshall/documents/projects/authenticationgolang/helloworld.go:40 +0x530
net/http.HandlerFunc.ServeHTTP(0x12ea668, 0x14022c0, 0xc42014a0e0, 0xc420144100)
    /usr/local/Cellar/go/1.8.1/libexec/src/net/http/server.go:1942 +0x44
net/http.(*ServeMux).ServeHTTP(0x142e060, 0x14022c0, 0xc42014a0e0, 0xc420144100)
    /usr/local/Cellar/go/1.8.1/libexec/src/net/http/server.go:2238 +0x130
net/http.serverHandler.ServeHTTP(0xc42009a2c0, 0x14022c0, 0xc42014a0e0, 0xc420144100)
    /usr/local/Cellar/go/1.8.1/libexec/src/net/http/server.go:2568 +0x92
net/http.(*conn).serve(0xc4201360a0, 0x1402780, 0xc42011e580)
    /usr/local/Cellar/go/1.8.1/libexec/src/net/http/server.go:1825 +0x612
created by net/http.(*Server).Serve
    /usr/local/Cellar/go/1.8.1/libexec/src/net/http/server.go:2668 +0x2ce
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • douge3830 2017-05-18 05:30
    已采纳

    From error message that you got :

    runtime error: invalid memory address or nil pointer dereference goroutine 20 [running]:

    Your db varible in your hanlder() is nil that's the root of the cause.

    to fix this you can remove your : in your initialiseDB(). Because here you are assign to new variable local in the function not to your global variable. Like this :

    func initialiseDB() {
        var err error
        db, err = sql.Open("mysql", "root:@/authenticationgolang")
    
        if err != nil {
            panic(err.Error())
        }
    }
    

    Suggestion

    And then on your code please check the error value returned by the function like :

    data := UserRegistrationData{email, password}
        jsonEncoded, err := json.Marshal(data)
        if err !=nil {
            myLogger.Fatal(err)
        }
    
        myLogger.Println("Success")
    
        hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
        if err != nil {
           myLogger.Fatal(err)
        }
        _, err = db.Exec("INSERT INTO users (email, password) VALUES (?, ?)", email, hashedPassword)
       if err != nil {
           myLogger.Fatal(err)
       }
    

    Or you can use Println() in case you don't want to stop your application to run like this :

    if err != nil {
       myLogger.Println(err)
       return
    }
    

    The return will stop the execution of the code. Using this approach you will notice if somethings error happens on your server side and you know which line the error happened.

    And don't forget to send your response if the request success like :

    resp := struct {
        Message string
    }{
        Message : "your message",
    }
    
    // Write the response
    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(resp)
    

    Hope it helps.

    已采纳该答案
    打赏 评论

相关推荐 更多相似问题