Go-异常处理
Go中的异常
Go异常笼统的分为两种:Panic和Error
一般情况下,我们都要避免去使用Panic,使用Error并输出结果才是我们想要的
装饰器模式处理Error
http服务器hanlderFunc
其中要用到一个handler函数,我们觉得不能就暴力的返回系统自身的错误出去,所以进行装饰器模式的一层处理
func main() {
http.HandleFunc("/",
errWrapperAppHandler(filelist.HandlerFileList))
err := http.ListenAndServe(":8888", nil)
if err != nil {
fmt.Println(err)
return
}
}
处理方式
// 碰到错误就return,在外面处理err
type appHandler func(writer http.ResponseWriter,
request *http.Request) error
// 这就是装饰器模式,把这个handler包装了一下
func errWrapperAppHandler(handler appHandler) func(http.ResponseWriter, *http.Request) {
return func(writer http.ResponseWriter, request *http.Request) {
// recover一下
defer func() {
r := recover()
if r == nil {
return
}
log.Printf("Panic: %v", r)
http.Error(writer,
http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
}()
err := handler(writer, request)
if err != nil {
if userError, ok := err.(userError); ok {
http.Error(writer,
userError.Message(),
http.StatusInternalServerError)
return
}
log.Printf("Error occurred"+
"handleing request: %s",
err.Error())
code := http.StatusOK
switch {
case os.IsNotExist(err):
code = http.StatusNotFound
default:
// 系统内部错误
code = http.StatusInternalServerError
}
http.Error(writer,
http.StatusText(code), // 处理了内部的错误
code)
}
}
}
处理系统本身的错误
如果发生了系统本身的错误,并且是用户可以知道的那种,而我们想让用户知道这些错误,比如它的路径写错了
那就如下处理
这里的操作是新建了一个类型的userError,在外面实现了它,之后如果handler返回出来的是userError说明这是用户可见的,我们就把里面的message返回出来给传给前端
if userError, ok := err.(userError); ok {
http.Error(writer,
userError.Message(),
http.StatusInternalServerError)
return
}
处理handler抛出来的panic
我们不想预见panic的存在,所以对panic我们进行recover
defer func() {
r := recover()
if r == nil {
return
}
log.Printf("Panic: %v", r)
http.Error(writer,
http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
}()