跳至主要內容

错误处理

程序员李某某原创Golang框架源码错误小于 1 分钟

错误处理

宕机风险

先看一个简单的代码

func main() {
	r := lee.New()
	r.Get("/panic", func(c *lee.Context) {
		names := []string{"lee"}
		c.String(http.StatusOK, names[100])
	})
	r.Run(":8080")
}

一旦访问这个接口,就会因角标越界而宕机

错误捕获中间件

现在到了发挥中间件方便之处了,我们自定义一个这样的通用的中间件


func Recovery() HandleFunc {
	return func(c *Context) {
		defer func() {
			if err := recover(); err != nil {
				message := fmt.Sprintf("%s", err)
				log.Printf("%s\n\n", trace(message))
				c.Fail(http.StatusInternalServerError, "Internal Server Error")
			}
		}()

		c.Next()
	}
}

// print stack trace for debug
func trace(message string) string {
	var pcs [32]uintptr
	n := runtime.Callers(3, pcs[:]) // skip first 3 caller

	var str strings.Builder
	str.WriteString(message + "\nTraceback:")
	for _, pc := range pcs[:n] {
		fn := runtime.FuncForPC(pc)
		file, line := fn.FileLine(pc)
		str.WriteString(fmt.Sprintf("\n\t%s:%d", file, line))
	}
	return str.String()
}

挂载默认中间件

我们再够一个方法,生成默认带有Logger、Recovery的Engine

func Default() *Engine {
	e := New()
	e.Use(Logger(), Recovery())
	return e
}

测试

func main() {
	r := lee.Default()
	r.Get("/panic", func(c *lee.Context) {
		names := []string{"lee"}
		c.String(http.StatusOK, names[100])
	})
	r.Run(":8080")
}
上次编辑于:
贡献者: ext.liyuanhao3