duandu1049 2017-05-18 05:05
浏览 91
已采纳

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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘