2017-05-18 11 views
1

現在、GolangにPOST要求を処理し、データをMySQLデータベースに格納するコードを記述しています。Golang - MySQL DBにデータを挿入中に予期しないストリームの終了

ここまではこれまでに書いたことがあります。

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) 
} 

コードを実行してデータを保存しようとすると、次のメッセージが表示されます。

unexpected end of stream on Connection{10.10.10.153:8080, [email protected]=/10.10.10.153:8080 cipherSuite=none protocol=http/1.1}

ログには、この行に問題があることを指摘しているようだ、と私はこれを固定するための誰かにお願いしたいと思います。

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

を追加しましたここで私は、コンソール上で取得したログメッセージです。それが原因のルートだnilをごhanlder()

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

あなたdb varibleがある:あなたが得たエラーメッセージから

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 

答えて

2

これを修正するには、initialiseDB():を削除してください。ここでは、グローバル変数ではなく、関数内の新しい変数localに代入されるためです。このように:

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

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

提案

そして、あなたのコード上のような関数によって返されるエラー値を確認してください。

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) 
    } 

それとも、あなたはケースにPrintln()を使用することができますアプリケーションを次のように実行しないようにしないでください。

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

戻りコードの実行を停止します。このアプローチを使用すると、サーバー側で何らかのエラーが発生し、エラーが発生した行がわかっている場合に気付くでしょう。

など要求成功ならば、あなたの応答を送信することを忘れないでください:

resp := struct { 
    Message string 
}{ 
    Message : "your message", 
} 

// Write the response 
w.WriteHeader(http.StatusOK) 
json.NewEncoder(w).Encode(resp) 

はそれがお役に立てば幸いです。

+0

答えに感謝しますが、私はコードに苦労しています。私は質問にログを追加して、あなたはそれをチェックしてもらえますか? –

+0

@ MarshallS.Lee更新された回答を参照してください –

+1

はい私はあなたの答えをチェックアウトし、私のコードに反映しました。それは正常に動作しており、あなたの助けに感謝! :) –

関連する問題