golang http 恐慌的全局恢复处理程序
Posted
技术标签:
【中文标题】golang http 恐慌的全局恢复处理程序【英文标题】:global recover handler for golang http panic 【发布时间】:2015-04-29 00:26:53 【问题描述】:我想创建全局错误处理程序以通过电子邮件发送。
package main
import (
"github.com/gorilla/mux"
"log"
"net/http"
)
func main()
rtr := mux.NewRouter()
rtr.HandleFunc("/", withPanic).Methods("GET")
http.Handle("/", rtr)
log.Println("Listening...")
http.ListenAndServe(":3001", http.DefaultServeMux)
func withPanic(w http.ResponseWriter, r *http.Request)
panic("somewhere here will be panic, but I don't know where exactly")
如何使其全球化。如果我知道哪里会出错就很容易了
if err != nil
sendMeMail(err)
但是,如果我不知道哪里会发生错误,该怎么办?所以我应该添加一个全局recover
ish 处理程序。但是具体怎么做我不知道。
更新
我在main
的开头添加了defer recover
,但它在请求http://localhost:3001
时从未执行。所以恐慌不会通过电子邮件发送。
package main
import (
"errors"
"fmt"
"github.com/gorilla/mux"
"log"
"net/http"
)
func main()
defer func()
if r := recover(); r != nil
fmt.Println("Recovered in f", r)
// find out exactly what the error was and set err
var err error
switch x := r.(type)
case string:
err = errors.New(x)
case error:
err = x
default:
err = errors.New("Unknown panic")
if err != nil
// sendMeMail(err)
fmt.Println("sendMeMail")
()
rtr := mux.NewRouter()
rtr.HandleFunc("/", withPanic).Methods("GET")
http.Handle("/", rtr)
log.Println("Listening...")
http.ListenAndServe(":3001", http.DefaultServeMux)
func withPanic(w http.ResponseWriter, r *http.Request)
panic("somewhere here will be panic, but I don't know where exactly")
【问题讨论】:
【参考方案1】:您可以将处理程序包装在恢复中间件中
package main
import (
"errors"
"github.com/gorilla/mux"
"log"
"net/http"
)
func main()
m := mux.NewRouter()
m.Handle("/", RecoverWrap(http.HandlerFunc(handler))).Methods("GET")
http.Handle("/", m)
log.Println("Listening...")
http.ListenAndServe(":3001", nil)
func handler(w http.ResponseWriter, r *http.Request)
panic(errors.New("panicing from error"))
func RecoverWrap(h http.Handler) http.Handler
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request)
defer func()
r := recover()
if r != nil
var err error
switch t := r.(type)
case string:
err = errors.New(t)
case error:
err = t
default:
err = errors.New("Unknown error")
sendMeMail(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
()
h.ServeHTTP(w, r)
)
func sendMeMail(err error)
// send mail
您可以查看codahale recovery handler 或negroni middleware 了解更多详情。
【讨论】:
e.Error() 应该是 err.Error()? 固定@eyeAppsLLC。 非常简洁的解决方案r := recover()
从外部函数中隐藏 r *http.Request
。如果您想在恢复块中访问它 - 最好更改名称,例如e := recover()
【参考方案2】:
我相信这就是gorilla recovery handler 的用途
【讨论】:
以上是关于golang http 恐慌的全局恢复处理程序的主要内容,如果未能解决你的问题,请参考以下文章
golang Go Web Applications中的自定义处理程序和避免全局 - http://elithrar.github.io/article/custom-handlers-avoidi
golang Go Web Applications中的自定义处理程序和避免全局 - http://elithrar.github.io/article/custom-handlers-avoidi