Gin-Gonic框架中创建用户时的空指针引用问题排查
Golang用户创建功能空指针错误排查
问题描述
我正在使用Golang实现用户创建功能,在UserImplementation结构体中定义了接收User模型指针的CreateUser()函数,用于在数据库中创建新用户记录。但运行该函数时持续出现“Nil pointer”错误,需要排查问题所在。
相关代码
CreateUser() 函数实现
func (usr *UserImplementation) CreateUser(user *models.User) (*models.User, error) { fmt.Println("User date", user.CreatedAt) fmt.Println("User name", user.FirstName) fmt.Println("User data", user.Password) pg := databaseapi.NewApiConfig{} params := database_utils.CreateUserParams{ ID: uuid.New(), CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC(), FirstName: user.FirstName, LastName: user.LastName, OtherName: user.OtherName, Password: user.Password, Email: user.Email, ProfileImage: user.ProfileImage, Status: user.Status, Username: user.Username, IsAdmin: user.IsAdmin, Role: user.Role, Gender: user.Gender, PhoneNumber: user.PhoneNumber, } userResponse, err := pg.ApiConfig.DB.CreateUser(usr.ctx, params) if err != nil { return nil, fmt.Errorf("error: %v", err.Error()) } return (*models.User)(&userResponse), nil }
UserController 结构体及方法
type UserController struct { UserCtrl *usersimpl.UserImplementation } func (usrCtrl *UserController) CreateUser(ctx *gin.Context) { var user models.User if err := ctx.ShouldBindJSON(&user); err != nil { ctx.JSON(http.StatusBadRequest, gin.H{ "Error": err.Error(), }) return } _, err := utilities.EmailValidator(user.Email) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{ "Error": err.Error(), }) return } hashPassword, err := utilities.HashPassword(user.Password) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{ "Error": err.Error(), }) } user.Password = hashPassword resp, err := usrCtrl.UserCtrl.CreateUser(&user) if err != nil { ctx.JSON( http.StatusBadRequest, gin.H{ "Error": err.Error(), }, ) return } ctx.JSON(http.StatusOK, gin.H{ "response": resp, }) }
UserImplementation 结构体及构造函数
type UserImplementation struct { pg *database_utils.Queries ctx context.Context } func NewUserService(pg *database_utils.Queries, ctx context.Context) *UserImplementation { return &UserImplementation{ pg: pg, ctx: ctx, } }
错误原因分析
- 数据库实例未初始化:
CreateUser函数中创建的pg := databaseapi.NewApiConfig{}是空结构体,ApiConfig.DB字段未被赋值,调用pg.ApiConfig.DB.CreateUser时触发空指针错误。 - 冗余的实例创建:
UserImplementation结构体本身已通过构造函数注入了pg *database_utils.Queries实例,无需重新创建databaseapi.NewApiConfig,直接使用自带的pg即可。 - 服务实例未正确注入:如果
UserController的UserCtrl字段未通过NewUserService初始化赋值,调用usrCtrl.UserCtrl.CreateUser时也会触发空指针错误。
修复方案
修正 CreateUser 函数
去掉冗余的数据库实例创建,直接使用结构体自带的pg字段:
func (usr *UserImplementation) CreateUser(user *models.User) (*models.User, error) { fmt.Println("User date", user.CreatedAt) fmt.Println("User name", user.FirstName) fmt.Println("User data", user.Password) params := database_utils.CreateUserParams{ ID: uuid.New(), CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC(), FirstName: user.FirstName, LastName: user.LastName, OtherName: user.OtherName, Password: user.Password, Email: user.Email, ProfileImage: user.ProfileImage, Status: user.Status, Username: user.Username, IsAdmin: user.IsAdmin, Role: user.Role, Gender: user.Gender, PhoneNumber: user.PhoneNumber, } // 使用结构体自带的pg实例调用数据库方法 userResponse, err := usr.pg.CreateUser(usr.ctx, params) if err != nil { return nil, fmt.Errorf("error: %v", err.Error()) } return (*models.User)(&userResponse), nil }
确保服务实例正确注入
初始化UserController时,必须传入通过NewUserService创建的实例:
// 假设已初始化database_utils.Queries实例dbQueries和上下文ctx userService := usersimpl.NewUserService(dbQueries, ctx) userController := &UserController{ UserCtrl: userService, }
额外检查
- 确认
database_utils.Queries实例在注入时不为nil,确保数据库连接已正确建立。 - 检查
ctx.ShouldBindJSON(&user)的绑定结果,该操作的错误已被捕获,不会直接导致空指针。
内容的提问来源于stack exchange,提问作者Daniel Dexoangle
相关产品推荐
相关产品推荐

