【问题标题】:How to return mysql Query error from a DAO function in Golang如何从 Golang 中的 DAO 函数返回 mysql 查询错误
【发布时间】:2021-03-17 10:35:23
【问题描述】:

我想从 DAO 函数向调用者返回 MySQL Query 错误。但是错误会创建一个panic 并停止程序。所以没有任何东西返回给调用者。 DAQ功能如下

var sqlquery="SELECT idfrom table where id=?"

func (mdao DbConn) Daoprocess(tz *entities.Workflowentity) ([]entities.WorkflowResponseEntity, error) {
    log.Println("In side dao")
    values := []entities.WorkflowResponseEntity{}
    rows, err := mdao.DB.Query(sqlquery, tz.Id)
    defer rows.Close()
    if err != nil {
       //code halts here. Nothing returns after here
       return values, err
    }
   for rows.Next() {
       value := entities.WorkflowResponseEntity{}
        err:=rows.Scan(&value.Id)
       if err != nil {
          log.Print("Daoprocess Scan Error", err)
           return values, err
       }
       values = append(values, value)
   }
   return values, nil
}

我的调用函数是这样的

values, err1 := dataAccess.Daoprocess(tz)
log.Print("\n\n INSIDE MODEL")
log.Print(err1)
if err1 != nil {
    return t, false, err1, "Something Went Wrong"
}

错误是:

2021/03/17 15:41:14 http: panic serving [::1]:53440: runtime error: invalid memory address or nil pointer dereference
goroutine 6 [running]:
net/http.(*conn).serve.func1(0xc00010cb40)
    /usr/local/go/src/net/http/server.go:1801 +0x147
panic(0x8c7460, 0xc419e0)
    /usr/local/go/src/runtime/panic.go:975 +0x3e9
database/sql.(*Rows).close(0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/go/src/database/sql/sql.go:3155 +0x76
database/sql.(*Rows).Close(0x0, 0x0, 0x0)
    /usr/local/go/src/database/sql/sql.go:3151 +0x33
panic(0x8c7460, 0xc419e0)
    /usr/local/go/src/runtime/panic.go:969 +0x175
database/sql.(*Rows).Next(0x0, 0xa095e0)
    /usr/local/go/src/database/sql/sql.go:2835 +0x30
iFIX/ifix/dao.DbConn.Checkprocessdelete(0xc000071d40, 0xc0001167e0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /home/subham/Documents/Projects/go/iFIX/ifix/dao/workflowdao.go:85 +0x227
iFIX/ifix/models.Checkprocessdelete(0xc0001167e0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /home/subham/Documents/Projects/go/iFIX/ifix/models/workflowmodel.go:350 +0x288
iFIX/ifix/handlers.Checkprocessdelete(0xa08c20, 0xc00017a0e0, 0xc00017e000)
    /home/subham/Documents/Projects/go/iFIX/ifix/handlers/workflowHandler.go:292 +0x237
net/http.HandlerFunc.ServeHTTP(0x9868d0, 0xa08c20, 0xc00017a0e0, 0xc00017e000)
    /usr/local/go/src/net/http/server.go:2042 +0x44
iFIX/ifix/router.PostMiddleware.func1(0xa08c20, 0xc00017a0e0, 0xc00017e000)
    /home/subham/Documents/Projects/go/iFIX/ifix/router/router.go:45 +0x659
net/http.HandlerFunc.ServeHTTP(0xc000178a00, 0xa08c20, 0xc00017a0e0, 0xc00017e000)
    /usr/local/go/src/net/http/server.go:2042 +0x44
net/http.(*ServeMux).ServeHTTP(0xc53460, 0xa08c20, 0xc00017a0e0, 0xc00017e000)
    /usr/local/go/src/net/http/server.go:2417 +0x1ad
net/http.serverHandler.ServeHTTP(0xc00017a000, 0xa08c20, 0xc00017a0e0, 0xc00017e000)
    /usr/local/go/src/net/http/server.go:2843 +0xa3
net/http.(*conn).serve(0xc00010cb40, 0xa095a0, 0xc000058300)
    /usr/local/go/src/net/http/server.go:1925 +0x8ad
created by net/http.(*Server).Serve
    /usr/local/go/src/net/http/server.go:2969 +0x36c

我想处理错误并将其返回给调用者。但是它会产生恐慌。如何将其传递给调用者函数?

【问题讨论】:

  • 请注意,堆栈跟踪显示恐慌来自DbConn.Checkprocessdelete,但您的代码示例显示了方法DbConn.Daoprocess。在查看不会导致恐慌的代码时,我们很难帮助您解决恐慌。
  • @mkopriva 我将 Checkprocessdelete 重命名为 Daoprocess 以便更好地理解。忘记从错误日志中删除它。两者功能相同

标签: mysql go error-handling


【解决方案1】:

在nil错误检查后移动defer close func,例如:

if err != nil {
   //code halts here. Nothing returns after here
   return values, err
}
defer rows.Close()

【讨论】:

  • 我以前做过。但问题是,如果发生错误,则不会调用 rows. close() 函数。
  • @Subham 如果Query 返回错误,则无需关闭rows,因为在这种情况下rows 将是nil,这就是您得到恐慌。因此,在首先确定Query 成功之前,无需调用rows.Close()。 Matteo 的回答是正确的。
  • @Subham 这仅表示您没有在您的应用中某处正确释放连接,可以在任何地方,不一定是Checkprocessdelete。尽管如此,事实是,在 nil*sql.Rows 值上调用 Close 总是会恐慌。
  • @Subham 确保您从不使用_, err := db.Query(..._, := QueryRow(...,如果您不关心查询结果,请使用_, err := db.Exec(...。始终使用Query 时,首先检查错误后,调用rows.Close()。使用QueryRow 时始终调用row.Scan(...
  • 请注意,如果err 不是,则不能保证rows 将是nil。一般你想defer func(){ if rows != nil { rows.Close() } }不管err == nil。大多数资源也是如此 - 如果资源不是 nil,则无论错误值如何,都应该安全且有必要关闭它。
猜你喜欢
  • 1970-01-01
  • 2012-03-20
  • 1970-01-01
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
  • 2013-11-07
  • 2016-12-16
  • 2019-08-22
相关资源
最近更新 更多