Gorm Panic golang:运行时错误:无效的内存地址或空指针解引用。

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

Gorm Panic golang : panic serving runtime error: invalid memory address or nil pointer dereference

问题

我正在尝试解决这个恐慌错误,我刚刚在GOLANG中创建了一个后端,那段代码是我的第一步,如果你看到了一些错误,请告诉我!

这是代码的第一部分,主要是Main函数(main.go),位于main包中:

如果你看到,我们有两个函数:

  • main()
  • BindRoutes(function()) -> 当从main函数调用时,它接收一个绑定器
func main() {
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal(err)
    }

    // 数据库变量用于结构体
    host := os.Getenv("POSTGRES_HOST")
    user := os.Getenv("POSTGRES_USER")
    port := os.Getenv("POSTGRES_PORT")
    password := os.Getenv("POSTGRES_PASSWORD")
    dbname := os.Getenv("POSTGRES_DB")

    // 服务器变量
    PORT := os.Getenv("PORT")
    JWT_SECRET := os.Getenv("JWT_SECRET")
    DB_URL := os.Getenv("DATA_BASE_URL")

    server, err := server.NewServer(context.Background(), &server.Config{
        JWTSecret:   JWT_SECRET,
        Port:        PORT,
        DatabaseUrl: DB_URL,
    })

    if err != nil {
        log.Fatal(err)
    }

    db := config.Database{
        Host:     host,
        Port:     port,
        User:     user,
        Password: password,
        Dbname:   dbname,
    }

    db.Open()

    server.Start(BindRoutes)
}

func BindRoutes(s server.Server, r *mux.Router, db *config.Database) {
    r.HandleFunc("/blog/newblog", handler.CreateNewBlog(s, db)).Methods(http.MethodPost)
}

接下来是SERVER包:

这里有两个结构体和一个接口,最重要的部分是绑定器,我不知道我是否实现得好。

package server

import (
    "context"
    "errors"
    "log"
    "net/http"

    "github.com/felipeolayao1998/backdiariodeuninge/config"
    "github.com/gorilla/mux"
)

type Config struct {
    Port        string
    JWTSecret   string
    DatabaseUrl string
}

type Server interface {
    Config() *Config
}

type Broker struct {
    config *Config
    router *mux.Router
}

func (b *Broker) Config() *Config {
    return b.config
}

func NewServer(ctx context.Context, config *Config) (*Broker, error) {
    if config.Port == "" {
        return nil, errors.New("port is required")
    }
    if config.JWTSecret == "" {
        return nil, errors.New("jwt secret is required")
    }
    if config.DatabaseUrl == "" {
        return nil, errors.New("database url is required")
    }
    broker := &Broker{
        config: config,
        router: mux.NewRouter(),
    }
    return broker, nil
}

func (b *Broker) Start(binder func(s Server, r *mux.Router, db *config.Database)) {
    b.router = mux.NewRouter()
    binder(b, b.router, &config.Database{})
    log.Println("starting server on port", b.config.Port)
    if err := http.ListenAndServe(b.config.Port, b.router); err != nil {
        log.Println("error starting server:", err)
    } else {
        log.Fatalf("server stopped")
    }
}

Models:

package Models

type Blog struct {
    Id      string `json:"id" gorm:"type:string;default:string;primary_key;unique"`
    Name    string `json:"name" gorm:"type:varchar(255);not null"`
    Content string `json:"content" gorm:"type:varchar(2000);not null"`
    Likes   int    `json:"likes" gorm:"type:integer"`
}

Handler:

这里有个问题,当我调用create函数时,它返回一个恐慌错误,你可以在问题的最后看到。

func CreateNewBlog(s server.Server, db *config.Database) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-type", "application/json")
        w.WriteHeader(http.StatusOK)

        db.Db.Create(&models.Blog{Id: "1", Name: "Felipe", Content: "fdasfasfa", Likes: 1}) // 这里是问题所在

    }
}

2023/04/07 21:25:46 starting server on port :8000
0xc00043a028 &{a2081199-a75e-4b3e-9551-3442a0fe0d21 Felipe contenido ejempo 1}
2023/04/07 21:25:55 http: panic serving [::1]:59553: runtime error: invalid memory address or nil pointer dereference
goroutine 18 [running]:
net/http.(*conn).serve.func1()
C:/Program Files/Go/src/net/http/server.go:1850 +0xbf
panic({0x1620000, 0x1c52680})
C:/Program Files/Go/src/runtime/panic.go:890 +0x262
gorm.io/gorm.(*DB).Create(0x17e44c0?, {0x15d11c0?, 0xc00041c180?})
C:/Users/Bymet/go/pkg/mod/gorm.io/gorm@v1.24.7-0.20230306060331-85eaf9eeda11/finisher_api.go:18 +0x22
github.com/felipeolayao1998/backdiariodeuninge/handler.CreateNewBlog.func1({0x17ea340, 0xc000424000}, 0xc00042c100)
D:/PodCast/PaginaWeb/backend/handler/handlerBlog.go:69 +0x3e5

英文:

I'm trying to solve this panic error, i'm just created a backend in GOLANG, that code was my first steps, also if u see some mistakes, tell me!.

Here was the firts part of code , the Main: (main.go) into the package main:

if you see we have 2 functions

  • main()

  • BindRoutes(function()) -> it recieves a binder when it's called from the main

    func main() {
    err := godotenv.Load(".env")
    if err != nil {
    log.Fatal(err)
    }
    // Variables de la base de datos para el struct
    host := os.Getenv("POSTGRES_HOST")
    user := os.Getenv("POSTGRES_USER")
    port := os.Getenv("POSTGRES_PORT")
    password := os.Getenv("POSTGRES_PASSWORD")
    dbname := os.Getenv("POSTGRES_DB")
    // Variables del servidor
    PORT := os.Getenv("PORT")
    JWT_SECRET := os.Getenv("JWT_SECRET")
    DB_URL := os.Getenv("DATA_BASE_URL")
    server, err := server.NewServer(context.Background(), &server.Config{
    JWTSecret:   JWT_SECRET,
    Port:        PORT,
    DatabaseUrl: DB_URL,
    })
    if err != nil {
    log.Fatal(err)
    }
    db := config.Database{
    Host:     host,
    Port:     port,
    User:     user,
    Password: password,
    Dbname:   dbname,
    }
    db.Open()
    server.Start(BindRoutes)
    }
    func BindRoutes(s server.Server, r *mux.Router, db *config.Database) {
    r.HandleFunc("/blog/newblog", handler.CreateNewBlog(s, db)).Methods(http.MethodPost)
    }
    

Next we have the SERVER package

Here we have 2 structs and 1 interface, there the most important part is the binder, there I don't know if i implemented good.

```
package server
import (
"context"
"errors"
"log"
"net/http"
"github.com/felipeolayao1998/backdiariodeuninge/config"
"github.com/gorilla/mux"
)
type Config struct {
Port        string
JWTSecret   string
DatabaseUrl string
}
type Server interface {
Config() *Config
}
type Broker struct {
config *Config
router *mux.Router
}
func (b *Broker) Config() *Config {
return b.config
}
func NewServer(ctx context.Context, config *Config) (*Broker, error) {
if config.Port == "" {
return nil, errors.New("port is required")
}
if config.JWTSecret == "" {
return nil, errors.New("jwt secret is required")
}
if config.DatabaseUrl == "" {
return nil, errors.New("database url is required")
}
broker := &Broker{
config: config,
router: mux.NewRouter(),
}
return broker, nil
}
func (b *Broker) Start(binder func(s Server, r *mux.Router, db *config.Database)) {
b.router = mux.NewRouter()
binder(b, b.router, &config.Database{})
log.Println("starting server on port", b.config.Port)
if err := http.ListenAndServe(b.config.Port, b.router); err != nil {
log.Println("error starting server:", err)
} else {
log.Fatalf("server stopped")
}
}
```

Models:

```
package Models
type Blog struct {
Id      string `json:"id" gorm:"type:string;default:string;primary_key;unique"`
Name    string `json:"name" gorm:"type:varchar(255);not null"`
Content string `json:"content" gorm:"type:varchar(2000);not null"`
Likes   int    `json:"likes" gorm:"type:integer" `
}
```

Handler:
Here i have the problem, when i call the create, it returns an PANIC as you can see at the end of this question.

   func CreateNewBlog(s server.Server, db *config.Database) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-type", "application/json")
w.WriteHeader(http.StatusOK)
db.Db.Create(&models.Blog{Id: "1", Name: "Felipe", Content: "fdasfasfa", Likes: 1}) //Here is the problem
}
}
2023/04/07 21:25:46 starting server on port :8000
0xc00043a028 &{a2081199-a75e-4b3e-9551-3442a0fe0d21 Felipe contenido ejempo 1}
2023/04/07 21:25:55 http: panic serving [::1]:59553: runtime error: invalid memory address or nil pointer dereference
goroutine 18 [running]:
net/http.(*conn).serve.func1()
C:/Program Files/Go/src/net/http/server.go:1850 +0xbf
panic({0x1620000, 0x1c52680})
C:/Program Files/Go/src/runtime/panic.go:890 +0x262
gorm.io/gorm.(*DB).Create(0x17e44c0?, {0x15d11c0?, 0xc00041c180?})
C:/Users/Bymet/go/pkg/mod/gorm.io/gorm@v1.24.7-0.20230306060331-85eaf9eeda11/finisher_api.go:18 +0x22
github.com/felipeolayao1998/backdiariodeuninge/handler.CreateNewBlog.func1({0x17ea340, 0xc000424000}, 0xc00042c100)
D:/PodCast/PaginaWeb/backend/handler/handlerBlog.go:69 +0x3e5 
</details>
# 答案1
**得分**: 2
你正在将一个未初始化的指针传递给`db`变量的`Db`字段的`Create`方法。
你可以尝试先初始化db连接。
```go
func CreateNewBlog(s server.Server, db *config.Database) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-type", "application/json")
w.WriteHeader(http.StatusOK)
// 初始化数据库连接
err := db.Open()
if err != nil {
log.Fatal(err)
}
// 在数据库中创建一个新的博客记录
db.Db.Create(&models.Blog{Id: "1", Name: "Felipe", Content: "fdasfasfa", Likes: 1})
}
}
英文:

You are passing an uninitialized pointer to the Create method of the Db field of the db variable.

Can you try to initialize the db connection first?

func CreateNewBlog(s server.Server, db *config.Database) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set(&quot;Content-type&quot;, &quot;application/json&quot;)
w.WriteHeader(http.StatusOK)
// Initialize the database connection
err := db.Open()
if err != nil {
log.Fatal(err)
}
// Create a new blog record in the database
db.Db.Create(&amp;models.Blog{Id: &quot;1&quot;, Name: &quot;Felipe&quot;, Content: &quot;fdasfasfa&quot;, Likes: 1})
}

}

huangapple
  • 本文由 发表于 2023年4月8日 10:53:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75963089.html
匿名

发表评论

匿名网友

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

确定