事件回调
HTTP Dispatcher没有Logger这个概念,而是抽象成了事件的概念。当调度器内出现错误时,会生成事件(httpdispatcher.Event),并将事件传递给传入的事件处理器,然后自行选择Logger来记录事件,目前支持404、405、500三种状态的事件。
- type Event struct {
- Status int // HTTP状态码
- Trace []string // 触发事件的trace
- Message error // 事件消息文本
- ResponseWriter http.ResponseWriter
- Request *http.Request
- }
示例如下:
- package main
- import (
- "github.com/dxvgef/httpdispatcher"
- "net/http"
- "fmt"
- )
- func main() {
- var dispatcher = httpdispatcher.New()
- dispatcher.Event.EnableTrace = true // 开启panic错误的trace
- dispatcher.Event.ShortCaller = true // trace消息中的源码文件记录短路径
- //传入一个事件处理函数,如果不传入此函数,则不会抛出任何事件
- dispatcher.Event.Handler = func(event *httpdispatcher.Event) {
- event.ResponseWriter.WriteHeader(event.Status)
- event.ResponseWriter.Write([]byte(http.StatusText(event.Status)))
- // 打印事件消息
- fmt.Println(event.Message.Error())
- // 打印trace,仅在500事件的时候event.Trace才有值
- if event.Status == 500 {
- var trace string
- trace += "\nTrace:"
- for k := range event.Trace {
- trace += "\n" + event.Trace[k]
- }
- fmt.Println(trace)
- }
- }
- svr := &http.Server{
- Addr: ":8080",
- Handler: dispatcher,
- }
- if err := svr.ListenAndServe(); err != nil {
- log.Fatal(err.Error())
- }
- }
注意,上面的代码并没有注册任何路由,在访问8080端口的任何路径都会触发404事件。
在路由处理器函数里,可以通过以下三种方法来触发500事件:
1. 运行时错误触发500事件
- dispatcher.Router.GET("/", func(ctx *httpdispatcher.Context) error {
- var s []int
- //此处有个下标越界的运行时错误
- println("通过运行时错误触发500事件", s[2])
- return nil
- })
2. 主动抛出panic触发500事件
- dispatcher.Router.GET("/", func(ctx *httpdispatcher.Context) error {
- panic("主动抛出panic触发500事件")
- return nil
- })
3. 路由处理器函数返回参数值不为nil,触发500事件
- dispatcher.Router.GET("/", func(ctx *httpdispatcher.Context) error {
- return errors.New("通过返回非nil触发500事件")
- })
直接使用return errors.New("…")
触发的500事件,trace中的信息太多,可以使用Context.Event
方法来精准定位到触发500事件的源码文件及行号,示例如下:
- dispatcher.Router.GET("/", func(ctx *httpdispatcher.Context) error {
- return ctx.Event(errors.New("通过Context.Return返回非nil触发500事件"))
- })