马提尼恢复任何恐慌
martini recover for any panics
我想将 RecoverWrap
连接到 martini 路由的所有处理程序,以使任何 panic
由 RecoverWrap
中的代码完成。
我试过像m.Use(RecoverWrap)
那样做,但不知道具体怎么做,编译失败。
package main
import (
"errors"
"github.com/go-martini/martini"
"net/http"
)
func main() {
m := martini.Classic()
//m.Use(RecoverWrap)
m.Get("/", func() {
panic("some panic")
})
m.Run()
}
func RecoverWrap(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
var err error
defer func() {
r := recover()
if r != nil {
switch t := r.(type) {
case string:
err = errors.New(t)
case error:
err = t
default:
err = errors.New("Unknown error")
}
http.Error(w, "Something goes wrong", http.StatusInternalServerError)
}
}()
h.ServeHTTP(w, req)
})
}
Martini 中的中间件处理程序无法到达 "wrap" 其他处理程序调用,因此注入器未找到 http.Handler。
你可以做的是使用 context.Next():
package main
import (
"errors"
"github.com/go-martini/martini"
"net/http"
)
func main() {
m := martini.Classic()
m.Use(RecoverWrap)
m.Get("/", func() {
panic("some panic")
})
m.Run()
}
func RecoverWrap(c martini.Context, w http.ResponseWriter) {
var err error
defer func(w http.ResponseWriter) {
r := recover()
if r != nil {
switch t := r.(type) {
case string:
err = errors.New(t)
case error:
err = t
default:
err = errors.New("Unknown error")
}
http.Error(w, "Something goes wrong", http.StatusInternalServerError)
}
}(w)
c.Next()
}
您必须确保您的错误处理程序是第一个注册的中间件,否则 运行 之前的那些处理程序将不会被捕获。
其实在martini.Recovery中实现了同样的方法:
https://github.com/go-martini/martini/blob/6241001738f6e1b1ea7c4a4089195e1b0681609a/recovery.go#L115
我想将 RecoverWrap
连接到 martini 路由的所有处理程序,以使任何 panic
由 RecoverWrap
中的代码完成。
我试过像m.Use(RecoverWrap)
那样做,但不知道具体怎么做,编译失败。
package main
import (
"errors"
"github.com/go-martini/martini"
"net/http"
)
func main() {
m := martini.Classic()
//m.Use(RecoverWrap)
m.Get("/", func() {
panic("some panic")
})
m.Run()
}
func RecoverWrap(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
var err error
defer func() {
r := recover()
if r != nil {
switch t := r.(type) {
case string:
err = errors.New(t)
case error:
err = t
default:
err = errors.New("Unknown error")
}
http.Error(w, "Something goes wrong", http.StatusInternalServerError)
}
}()
h.ServeHTTP(w, req)
})
}
Martini 中的中间件处理程序无法到达 "wrap" 其他处理程序调用,因此注入器未找到 http.Handler。
你可以做的是使用 context.Next():
package main
import (
"errors"
"github.com/go-martini/martini"
"net/http"
)
func main() {
m := martini.Classic()
m.Use(RecoverWrap)
m.Get("/", func() {
panic("some panic")
})
m.Run()
}
func RecoverWrap(c martini.Context, w http.ResponseWriter) {
var err error
defer func(w http.ResponseWriter) {
r := recover()
if r != nil {
switch t := r.(type) {
case string:
err = errors.New(t)
case error:
err = t
default:
err = errors.New("Unknown error")
}
http.Error(w, "Something goes wrong", http.StatusInternalServerError)
}
}(w)
c.Next()
}
您必须确保您的错误处理程序是第一个注册的中间件,否则 运行 之前的那些处理程序将不会被捕获。
其实在martini.Recovery中实现了同样的方法:
https://github.com/go-martini/martini/blob/6241001738f6e1b1ea7c4a4089195e1b0681609a/recovery.go#L115