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)
		}()
posted @ 2022-10-11 21:23  azxx  阅读(34)  评论(0编辑  收藏  举报