当我尝试使用`db.QueryRow`时,出现了Golang运行时错误。

huangapple go评论86阅读模式
英文:

golang runtime error when i am trying to use db.QueryRow

问题

我有一个controller.go文件:

package controller

import (
    "github.com/fishkaoff/todoList/pkg/postgresql"
    "github.com/gin-gonic/gin"
    "net/http"
    "context"
)

type Task struct {
    Title       string
    Description string
}

func GetTasks(c *gin.Context) {
    var response *Task
    err := db.Conn.QueryRow(context.Background(), "select * from tasks").Scan(&response.Title, &response.Description)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "error"})
    }

    c.JSON(200, gin.H{
        "page":  "gettasks",
        "tasks": response,
    })
}

当我发送请求时,它返回以下错误信息:

runtime error: invalid memory address or nil pointer dereference
C:/Program Files/Go/src/runtime/panic.go:260 (0xb7bab5)
        panicmem: panic(memoryError)
C:/Program Files/Go/src/runtime/signal_windows.go:255 (0xb7ba85)
        sigpanic: panicmem()
D:/workspace/golangWWW/pkg/mod/github.com/jackc/pgx/v4@v4.17.2/conn.go:551 (0x1015db1)
        (*Conn).Query: simpleProtocol := c.config.PreferSimpleProtocol
D:/workspace/golangWWW/pkg/mod/github.com/jackc/pgx/v4@v4.17.2/conn.go:663 (0x101b9dc)
        (*Conn).QueryRow: rows, _ := c.Query(ctx, sql, args...)
D:/workspace/golangWWW/todolist/internal/controller/controller.go:17 (0x101b9ab)
        GetTasks: err := db.Conn.QueryRow(context.Background(), "select * from tasks").Scan(&response.Title, &response.Description)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0xeb99c1)
        (*Context).Next: c.handlers[c.index](c)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/recovery.go:101 (0xeb99ac)
        CustomRecoveryWithWriter.func1: c.Next()
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0xeb8ac6)
        (*Context).Next: c.handlers[c.index](c)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/logger.go:240 (0xeb8aa9)
        LoggerWithConfig.func1: c.Next()
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0xeb7bd0)
        (*Context).Next: c.handlers[c.index](c)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:616 (0xeb7838)
        (*Engine).handleHTTPRequest: c.Next()
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:572 (0xeb74fc)
        (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
C:/Program Files/Go/src/net/http/server.go:2947 (0xd70feb)
        serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
C:/Program Files/Go/src/net/http/server.go:1991 (0xd6d6c6)
        (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
C:/Program Files/Go/src/runtime/asm_amd64.s:1594 (0xb96320)
        goexit: BYTE    $0x90   // NOP

db.Conn是从db.go导入的:

package db

import (
    "os"
    "fmt"
    "context"

    "github.com/jackc/pgx/v4/"
    "github.com/fishkaoff/todoList/internal/config"
)

var Conn *pgx.Conn

func InitDatabase(config config.Config) {
    Conn, err := pgx.Connect(context.Background(), config.DBUrl)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
        os.Exit(1)
    }
    defer Conn.Close()
}

InitDatabasemain.go中调用。

数据库表和列已创建。

我正在使用pgx v4版本。

P.S:对于我的糟糕英语表示抱歉,我不是以英语为母语的人。

英文:

i have controller.go:

package controller
import (
    "github.com/fishkaoff/todoList/pkg/postgresql"
    "github.com/gin-gonic/gin"
    "net/http"
    "context"
)

type Task struct {
    Title string 
    Description string
 }


func GetTasks(c *gin.Context) {
    var response *Task
    err := db.Conn.QueryRow(context.Background(), "select * from tasks").Scan(&response.Title, 
    &response.Description)
    if err != nil {
	    c.JSON(http.StatusInternalServerError, gin.H{"error":"error"})
    }

    c.JSON(200, gin.H{
	    "page":"gettasks",
	    "tasks": response,
    })
}

when i am sending request it returns me

```runtime error: invalid memory address or nil pointer dereference
C:/Program Files/Go/src/runtime/panic.go:260 (0xb7bab5)
        panicmem: panic(memoryError)
C:/Program Files/Go/src/runtime/signal_windows.go:255 (0xb7ba85)
        sigpanic: panicmem()
D:/workspace/golangWWW/pkg/mod/github.com/jackc/pgx/v4@v4.17.2/conn.go:551 (0x1015db1)
        (*Conn).Query: simpleProtocol := c.config.PreferSimpleProtocol
D:/workspace/golangWWW/pkg/mod/github.com/jackc/pgx/v4@v4.17.2/conn.go:663 (0x101b9dc)
        (*Conn).QueryRow: rows, _ := c.Query(ctx, sql, args...)
D:/workspace/golangWWW/todolist/internal/controller/controller.go:17 (0x101b9ab)
        GetTasks: err := db.Conn.QueryRow(context.Background(), "select * from tasks").Scan(&response.Title, &response.Description)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0xeb99c1)
        (*Context).Next: c.handlers[c.index](c)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/recovery.go:101 (0xeb99ac)
        CustomRecoveryWithWriter.func1: c.Next()
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0xeb8ac6)
        (*Context).Next: c.handlers[c.index](c)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/logger.go:240 (0xeb8aa9)
        LoggerWithConfig.func1: c.Next()
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0xeb7bd0)
        (*Context).Next: c.handlers[c.index](c)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:616 (0xeb7838)
        (*Engine).handleHTTPRequest: c.Next()
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:572 (0xeb74fc)
        (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
C:/Program Files/Go/src/net/http/server.go:2947 (0xd70feb)
        serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
C:/Program Files/Go/src/net/http/server.go:1991 (0xd6d6c6)
        (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
C:/Program Files/Go/src/runtime/asm_amd64.s:1594 (0xb96320)
        goexit: BYTE    $0x90   // NOP```

db.Conn is imported from db.go:

    package db


    import (
	    "os"
	    "fmt"
	    "context"


	    "github.com/jackc/pgx/v4/"
	    "github.com/fishkaoff/todoList/internal/config"
    )

    var Conn *pgx.Conn

    func InitDatabase(config config.Config) {
	    Conn, err := pgx.Connect(context.Background(), config.DBUrl)
	    if err != nil {
		    fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
		    os.Exit(1)
	    }
	    defer Conn.Close()
    }

InitDatabase is calling in main.go


in database table and columns are created


i am using pgx v4


P.S: sorry for my bad english, i am not a native speaker
⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣_________________________________________________________
⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣

答案1

得分: 2

你已经分配了内存来存储 *Task,而不是 Task

然后当你尝试获取 response.Titleresponse.Description 的地址时,这些字段没有地址,因为 response 是一个指针,但没有指向有效的任务。

尝试使用以下代码:

var response Task

现在你实际上已经为 TitleDescription 字段分配了空间,因此有地方来存储这些值。

英文:
    var response *Task

You have allocated memory to store a *Task, not a Task.

Then when you

    .Scan(&response.Title,     &response.Description)

Attempt to take the address of response.Title and response.Description. These fields don't have an address because response is a pointer but doesn't point to a valid task.

Try:

var response Task

Now you actually have allocated space for the Title and Description fields and thus have somewhere to store those values.

huangapple
  • 本文由 发表于 2022年9月17日 22:16:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/73755591.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定