N
N
nurzhannogerbek2019-06-06 10:52:41
PostgreSQL
nurzhannogerbek, 2019-06-06 10:52:41

How to fix "invalid memory address or nil pointer dereference" error?

Hello! Please help me understand the problem.
Using the IRIS framework, I wrote a REST service. I am using version 1.11.5 of Golang. When accessing a specific URL, I try to return all data from the reports table (PostgreSQL database) using the GORM library . When querying the database, an error occurs:

[WARN] 2019/06/06 13:31 Recovered from a route's Handler('constructor/controllers.glob..func1')
At Request: 200 /api/report/d5f9c639-13e6-42c1-9043-30783981724b GET ::1
Trace: runtime error: invalid memory address or nil pointer dereference

C:/Go/src/runtime/asm_amd64.s:522
C:/Go/src/runtime/panic.go:513
C:/Go/src/runtime/panic.go:82
C:/Go/src/runtime/signal_windows.go:204
C:/Users/NNogerbek/go/src/github.com/jinzhu/gorm/main.go:768
C:/Users/NNogerbek/go/src/github.com/jinzhu/gorm/main.go:179
C:/Users/NNogerbek/go/src/github.com/jinzhu/gorm/main.go:322
C:/Users/NNogerbek/go/src/constructor/controllers/report.go:14
C:/Users/NNogerbek/go/src/github.com/kataras/iris/context/context.go:1208
C:/Users/NNogerbek/go/src/github.com/kataras/iris/context/context.go:1217
C:/Users/NNogerbek/go/src/github.com/kataras/iris/middleware/logger/logger.go:50
C:/Users/NNogerbek/go/src/github.com/kataras/iris/middleware/logger/logger.go:31
C:/Users/NNogerbek/go/src/github.com/kataras/iris/context/context.go:1208
C:/Users/NNogerbek/go/src/github.com/kataras/iris/context/context.go:1217
C:/Users/NNogerbek/go/src/github.com/kataras/iris/middleware/recover/recover.go:56
C:/Users/NNogerbek/go/src/github.com/kataras/iris/context/context.go:922
C:/Users/NNogerbek/go/src/github.com/kataras/iris/context/context.go:1094
C:/Users/NNogerbek/go/src/github.com/kataras/iris/core/router/handler.go:227
C:/Users/NNogerbek/go/src/github.com/kataras/iris/core/router/router.go:84
C:/Users/NNogerbek/go/src/github.com/kataras/iris/core/router/router.go:161
C:/Go/src/net/http/server.go:2741
C:/Go/src/net/http/server.go:1847
C:/Go/src/runtime/asm_amd64.s:1333

Below is the complete code for the project. Can you please tell me where did you go wrong?
main.go:
package main

import (
  "constructor/database"
  "constructor/routes"
  "github.com/joho/godotenv"
  "github.com/kataras/iris"
)

func main()  {
  // Check the connection to remote PostgreSQL database with the help of the "gorm".
  database.ConnectPostgreSQL()
  defer database.DisconnectPostgreSQL()

  // Create an application with default logger and recovery middleware.
  application := iris.Default()

  // Define the list of all available routes of the application.
  routes.Handle(application)

  // Start to listen and serve the application.
  application.Run(iris.Addr(":8000" + port), iris.WithoutServerError(iris.ErrServerClosed))
}

database.go:
package database

import (
  "constructor/utils"
  "fmt"
  "github.com/jinzhu/gorm"
  _ "github.com/jinzhu/gorm/dialects/postgres"
)

var DBGORM *gorm.DB

func ConnectPostgreSQL() {
  // Initialize variables related with the remote PostgreSQL database.
  databaseUser := utils.CheckEnvironmentVariable("PostgreSQL_USER")
  databasePassword := utils.CheckEnvironmentVariable("PostgreSQL_PASSWORD")
  databaseHost := utils.CheckEnvironmentVariable("PostgreSQL_HOST")
  databaseName := utils.CheckEnvironmentVariable("PostgreSQL_DATABASE_NAME")

  // Define the connection string for the remote PostgreSQL database with the help of the "gorm" package.
  databaseURL:= fmt.Sprintf("host=%s user=%s dbname=%s password=%s sslmode=disable", databaseHost, databaseUser, databaseName, databasePassword)

  // Create connection pool to remote PostgreSQL database with the help of the "gorm" package.
  DBGORM, err := gorm.Open("postgres", databaseURL); if err != nil {
    utils.Logger().Println(err)
    panic(err)
  }

  // Ping the remote PostgreSQL database with the help of "gorm" package.
  err = DBGORM.DB().Ping(); if err != nil {
    utils.Logger().Println(err)
    panic(err)
  }

  // Enable logging mode of "gorm" package.
  DBGORM.LogMode(true)
}

func DisconnectPostgreSQL() error {
  return DBGORM.Close()
}

routes.go:
package routes

import (
  "constructor/controllers"
  "github.com/kataras/iris"
)

func Handle(application *iris.Application)  {
  application.Get("/api/report/{report_id:string}", controllers.GetReport)
}

controllers/report.go:
package controllers
import (
  "constructor/database"
  "constructor/utils"
  "github.com/kataras/iris"
)

type Report struct {
  ID int `gorm:"primary_key" json:"report_id"`
  Name string `json:"report_name"`
}

var GetReport = func(ctx iris.Context) {
  // Initialize variable.
  reportID := ctx.Params().Get("report_id")

  if utils.IsValidUUID(reportID) {
    var reports []Report
    database.DBGORM.Find(&reports) // <-ERROR
    ctx.JSON(reports)
  } else {
    ctx.StatusCode(iris.StatusBadRequest)
    ctx.JSON(iris.Map{"STATUS": "ERROR", "DESCRIPTION": "BAD REQUEST",})
  }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
N
nurzhannogerbek, 2019-06-06
@nurzhannogerbek

The problem was in the declaration of the DBGORM global variable in the database.go file . This variable reached the report.go file as nil, so panic occurred.
I had to change the database.go file:

var err error
DBGORM, err = gorm.Open("postgres", databaseURL); if err != nil {
  utils.Logger().Println(err)
  panic(err)
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question