Go 封装处理程序代码后出现错误500
我继承了其他两位开发人员编写的代码。看来,一个概念验证网站变成了生产代码,所以大部分代码都是主要的。理论上这是一个简单的程序。该设置是一个树莓pi,它控制用go编写的喷水装置,可以设置打开不同区域的时间表。我已经成功地将中继控制器封装到一个包中,现在我想封装ScheduleAPI。该部分是一个相当直接的CRUD操作。为了简单起见,我将在schedule_处理程序中的main和bare basics中发布我调用它的地方。因此,首先: main.goGo 封装处理程序代码后出现错误500,go,Go,我继承了其他两位开发人员编写的代码。看来,一个概念验证网站变成了生产代码,所以大部分代码都是主要的。理论上这是一个简单的程序。该设置是一个树莓pi,它控制用go编写的喷水装置,可以设置打开不同区域的时间表。我已经成功地将中继控制器封装到一个包中,现在我想封装ScheduleAPI。该部分是一个相当直接的CRUD操作。为了简单起见,我将在schedule_处理程序中的main和bare basics中发布我调用它的地方。因此,首先: main.go func main() { log.Se
func main() {
log.SetFlags(log.LstdFlags | log.LUTC)
log.SetOutput(&lumberjack.Logger{
Filename: "application.log",
MaxSize: 10, // megabytes
MaxBackups: 3,
MaxAge: 365, //days
LocalTime: false,
})
log.Printf("System Startup\n")
parseTemplates()
loadConfig()
config.Eth0Addr = getIPv4ForInterfaceName("eth0")
saveConfig()
log.Printf("local ethernet address: %s\n", config.Eth0Addr)
// gin.SetMode(gin.ReleaseMode)
gin.SetMode(gin.DebugMode)
r := gin.Default()
r.GET("/", mainGetHandler) // homepage
r.GET("/login", loginGetHandler)
r.POST("/login", loginPostHandler)
r.GET("/logout", authRequired(), logoutGetHandler)
scheduleRepository = nsScheduleRepository.Default("schedule.json")
parameters := nsScheduleApi.ScheduleHandlerParameters{
Engine: r,
Repository: scheduleRepository,
}
nsScheduleApi.Init(¶meters)
r.GET("/schedule", authRequired(), scheduleGetHandler)
http.Handle("/", r)
r.Static("/static/", "./static/")
config.URL = ""
// hack - wait 10 seconds for network to come up...
time.Sleep(10 * time.Second)
log.Println("Starting up on port 80")
log.Fatal(http.ListenAndServe(":80", r))
}
package api
import (
"mysprinkler/schedule"
"github.com/gin-gonic/gin"
"log"
"strconv"
)
type ScheduleHandlerParameters struct {
Repository schedule.ScheduleRepository
Engine *gin.Engine
}
var parameters *ScheduleHandlerParameters
func getSchedules(c *gin.Context) {
repository := parameters.Repository
circuitnum, _ := strconv.ParseInt(c.Query("circuitnum"), 10, 64)
log.Printf("[ScheduleHandler] getting schedules %d", circuitnum)
var scheds = make([]*schedule.Schedule2, 0)
if circuitnum > 0 {
schedule := repository.Get(string(circuitnum))
if schedule == nil {
// c.AbortWithStatus(404)
log.Printf("[ScheduleHandler] Could not find schedule '%d' in db", circuitnum)
} else {
scheds = append(scheds, schedule)
}
} else {
scheds = repository.GetAll()
}
c.JSON(200, scheds)
}
func getSchedule(c *gin.Context) {
repository := parameters.Repository
id := c.Params.ByName("id")
log.Printf("[ScheduleHandler] getting schedule %s", id)
sched := repository.Get(id)
c.JSON(200, sched)
}
func createSchedule(c *gin.Context) {
repository := parameters.Repository
var sched schedule.Schedule2
err := c.BindJSON(&sched)
if err != nil {
log.Printf("[ScheduleHandler] Error creating schedule %s", err)
} else {
log.Printf("[ScheduleHandler] insert schedule for circuit %d", sched.CircuitNum)
}
err = repository.InsertOrUpdate(&sched)
if err != nil {
c.AbortWithError(500, err)
return
}
logSchedule(&sched, "created")
c.JSON(200, sched)
}
func updateSchedule(c *gin.Context) {
repository := parameters.Repository
id := c.Params.ByName("id")
log.Printf("[ScheduleHandler] updating schedule %s", id)
sched := repository.Get(id)
c.BindJSON(&sched)
err := repository.InsertOrUpdate(sched)
if err != nil {
c.AbortWithError(500, err)
return
}
logSchedule(sched, "updated")
c.JSON(200, sched)
}
func deleteSchedule(c *gin.Context) {
repository := parameters.Repository
id := c.Params.ByName("id")
log.Printf("[ScheduleHandler] deleting schedule %s", id)
err := repository.Delete(id)
if err != nil {
c.Error(err)
return
}
c.JSON(200, gin.H{"id #" + id: "deleted"})
}
func logSchedule(sched *schedule.Schedule2, action string) {
log.Printf("schedule: %s\n", action)
log.Printf("*** id: %d\n", sched.ID)
log.Printf("*** load: %d\n", sched.CircuitNum+1)
log.Printf("*** on time: %s\n", sched.OnTime)
log.Printf("*** off time: %s\n", sched.OffTime)
log.Printf("*** enabled: %v", sched.Enabled)
log.Printf("*** sun: %v", sched.Sun)
log.Printf("*** mon: %v", sched.Mon)
log.Printf("*** tue: %v", sched.Tue)
log.Printf("*** wed: %v", sched.Wed)
log.Printf("*** thu: %v", sched.Thu)
log.Printf("*** fri: %v", sched.Fri)
log.Printf("*** sat: %v", sched.Sat)
}
// Init creates a handler for the schedule api
func Init(parameters *ScheduleHandlerParameters) {
parameters = parameters
r := parameters.Engine
r.GET("/schedule2", getSchedules)
r.GET("/schedule2/:id", getSchedule)
r.POST("/schedule2", createSchedule)
r.PUT("/schedule2/:id", updateSchedule)
r.DELETE("/schedule2/:id", deleteSchedule)
}
schedule/api/schedule\u handler.go
func main() {
log.SetFlags(log.LstdFlags | log.LUTC)
log.SetOutput(&lumberjack.Logger{
Filename: "application.log",
MaxSize: 10, // megabytes
MaxBackups: 3,
MaxAge: 365, //days
LocalTime: false,
})
log.Printf("System Startup\n")
parseTemplates()
loadConfig()
config.Eth0Addr = getIPv4ForInterfaceName("eth0")
saveConfig()
log.Printf("local ethernet address: %s\n", config.Eth0Addr)
// gin.SetMode(gin.ReleaseMode)
gin.SetMode(gin.DebugMode)
r := gin.Default()
r.GET("/", mainGetHandler) // homepage
r.GET("/login", loginGetHandler)
r.POST("/login", loginPostHandler)
r.GET("/logout", authRequired(), logoutGetHandler)
scheduleRepository = nsScheduleRepository.Default("schedule.json")
parameters := nsScheduleApi.ScheduleHandlerParameters{
Engine: r,
Repository: scheduleRepository,
}
nsScheduleApi.Init(¶meters)
r.GET("/schedule", authRequired(), scheduleGetHandler)
http.Handle("/", r)
r.Static("/static/", "./static/")
config.URL = ""
// hack - wait 10 seconds for network to come up...
time.Sleep(10 * time.Second)
log.Println("Starting up on port 80")
log.Fatal(http.ListenAndServe(":80", r))
}
package api
import (
"mysprinkler/schedule"
"github.com/gin-gonic/gin"
"log"
"strconv"
)
type ScheduleHandlerParameters struct {
Repository schedule.ScheduleRepository
Engine *gin.Engine
}
var parameters *ScheduleHandlerParameters
func getSchedules(c *gin.Context) {
repository := parameters.Repository
circuitnum, _ := strconv.ParseInt(c.Query("circuitnum"), 10, 64)
log.Printf("[ScheduleHandler] getting schedules %d", circuitnum)
var scheds = make([]*schedule.Schedule2, 0)
if circuitnum > 0 {
schedule := repository.Get(string(circuitnum))
if schedule == nil {
// c.AbortWithStatus(404)
log.Printf("[ScheduleHandler] Could not find schedule '%d' in db", circuitnum)
} else {
scheds = append(scheds, schedule)
}
} else {
scheds = repository.GetAll()
}
c.JSON(200, scheds)
}
func getSchedule(c *gin.Context) {
repository := parameters.Repository
id := c.Params.ByName("id")
log.Printf("[ScheduleHandler] getting schedule %s", id)
sched := repository.Get(id)
c.JSON(200, sched)
}
func createSchedule(c *gin.Context) {
repository := parameters.Repository
var sched schedule.Schedule2
err := c.BindJSON(&sched)
if err != nil {
log.Printf("[ScheduleHandler] Error creating schedule %s", err)
} else {
log.Printf("[ScheduleHandler] insert schedule for circuit %d", sched.CircuitNum)
}
err = repository.InsertOrUpdate(&sched)
if err != nil {
c.AbortWithError(500, err)
return
}
logSchedule(&sched, "created")
c.JSON(200, sched)
}
func updateSchedule(c *gin.Context) {
repository := parameters.Repository
id := c.Params.ByName("id")
log.Printf("[ScheduleHandler] updating schedule %s", id)
sched := repository.Get(id)
c.BindJSON(&sched)
err := repository.InsertOrUpdate(sched)
if err != nil {
c.AbortWithError(500, err)
return
}
logSchedule(sched, "updated")
c.JSON(200, sched)
}
func deleteSchedule(c *gin.Context) {
repository := parameters.Repository
id := c.Params.ByName("id")
log.Printf("[ScheduleHandler] deleting schedule %s", id)
err := repository.Delete(id)
if err != nil {
c.Error(err)
return
}
c.JSON(200, gin.H{"id #" + id: "deleted"})
}
func logSchedule(sched *schedule.Schedule2, action string) {
log.Printf("schedule: %s\n", action)
log.Printf("*** id: %d\n", sched.ID)
log.Printf("*** load: %d\n", sched.CircuitNum+1)
log.Printf("*** on time: %s\n", sched.OnTime)
log.Printf("*** off time: %s\n", sched.OffTime)
log.Printf("*** enabled: %v", sched.Enabled)
log.Printf("*** sun: %v", sched.Sun)
log.Printf("*** mon: %v", sched.Mon)
log.Printf("*** tue: %v", sched.Tue)
log.Printf("*** wed: %v", sched.Wed)
log.Printf("*** thu: %v", sched.Thu)
log.Printf("*** fri: %v", sched.Fri)
log.Printf("*** sat: %v", sched.Sat)
}
// Init creates a handler for the schedule api
func Init(parameters *ScheduleHandlerParameters) {
parameters = parameters
r := parameters.Engine
r.GET("/schedule2", getSchedules)
r.GET("/schedule2/:id", getSchedule)
r.POST("/schedule2", createSchedule)
r.PUT("/schedule2/:id", updateSchedule)
r.DELETE("/schedule2/:id", deleteSchedule)
}
在我看到的日志中
2018/05/20 12:14:36 System Startup
2018/05/20 12:14:36 local ethernet address: 10.0.0.7
2018/05/20 12:14:36 [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
2018/05/20 12:14:36 [GIN-debug] GET / --> main.mainGetHandler (3 handlers)
2018/05/20 12:14:36 [GIN-debug] GET /login --> main.loginGetHandler (3 handlers)
2018/05/20 12:14:36 [GIN-debug] POST /login --> main.loginPostHandler (3 handlers)
2018/05/20 12:14:36 [GIN-debug] GET /logout --> main.logoutGetHandler (4 handlers)
2018/05/20 12:14:36 [GIN-debug] GET /schedule2 --> sprinkler/schedule/api.getSchedules (3 handlers)
2018/05/20 12:14:36 [GIN-debug] GET /schedule2/:id --> sprinkler/schedule/api.getSchedule (3 handlers)
2018/05/20 12:14:36 [GIN-debug] POST /schedule2 --> sprinkler/schedule/api.createSchedule (3 handlers)
2018/05/20 12:14:36 [GIN-debug] PUT /schedule2/:id --> sprinkler/schedule/api.updateSchedule (3 handlers)
2018/05/20 12:14:36 [GIN-debug] DELETE /schedule2/:id --> sprinkler/schedule/api.deleteSchedule (3 handlers)
2018/05/20 12:14:36 [GIN-debug] GET /static/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)
2018/05/20 12:14:36 [GIN-debug] HEAD /static/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)
2018/05/20 12:14:46 Starting up on port 80
2018/05/20 12:15:15 admin logged in
但是当我导航到/schedule2时,模板被加载,然后立即得到两个内部500错误(每个调用/schedule2?circuitnum=1都有一个)。现在,这段代码以前可以工作了,当它在主程序中时,我只是将这些方法移动到schedule_api文件中,然后制作一个
Init
,并将设置代码放入其中。有了C#背景,我不明白为什么会这样。我的第一个猜测是,当调度处理程序退出Main
的范围时,我丢失了对它的引用,但我不明白为什么。知道我哪里出错了吗 没错!进行此操作时:
func Init(parameters *ScheduleHandlerParameters) {
parameters = parameters
// ....
}
参数
成为此函数的局部变量,下一行只是将其分配给自身。全局变量参数
仍然保持nil
值,从未更改。这导致了错误
将函数param更改为类似以下内容应该可以正常工作:
func Init(shPrms *ScheduleHandlerParameters) {
parameters = shPrms
// ....
}
我想我明白了。我必须测试以确定,但看起来init中的自我分配搞砸了。我将init上的参数重命名为不同的名称,它现在似乎可以工作了:我想您会后悔在这里使用全局变量。@bohdan_trotsenko我一直怀疑是否使用它。我还是个新手。什么是更好的练习?创建一个非导出结构来保存我的值?我建议使用一个带有参数的公共结构,只需删除全局变量。将函数更新为
*api.ScheduleHandlerParameters
上的方法;(这是最起码的;您可以更新或使用一组不同的结构/方法)