在go web中,难免会引发panic。比如用户在一次请求中输入了不正确的数据导致除0或者数组越界。如果不设置默认的错误处理,那程序就会崩溃退出,这显然是不能接受的。所以要实现一个默认的总错误处理。
依前文,现在项目中已经有如下结构:
src--|
handlers--|
test--|
test.go
logger--|
logger.go
|
main.go
在前篇文章中,我们实现了中间件。没错,handler默认的错误,我们就要从这个总入口入手: 把中间件处理改成:
// myHost 做中间件和Handler全局错误使用。免得一个panic把全局挂挂
func myHost(handler http.Handler) http.Handler {
ourFunc := func(w http.ResponseWriter, r *http.Request) {
var err error
defer func() {
rec := recover()
if rec != nil {
switch t := rec.(type) {
case string:
err = errors.New(t)
case error:
err = t
default:
err = errors.New("Unknown error")
}
http.Error(w, err.Error(), http.StatusInternalServerError)
logger.Errorln(
fmt.Sprintf("%s %s \n %s", r.Method, r.URL, err.Error()))
}
}()
//记录时间
start := time.Now()
handler.ServeHTTP(w, r)
logger.Infoln(
fmt.Sprintf("%s %s %s", r.Method, r.URL, time.Now().Sub(start)))
}
return http.HandlerFunc(ourFunc)
}
现在我们尝试在SayHello
这个handler中引发一个panic,不用担心,程序会记一个日志,而不是以挂挂告终了。