Skip to content
🎉 httpz v1.1.0 已发布
Docs指南错误集中处理

考虑下面的helloHandler,它返回error:

func helloHandler(w http.ResponseWriter, r *http.Request) error {
	w.Write([]byte("hello httpz"))
	return nil
}

httpz只是写了一个适配器,把上述的handler转为下面标准库的handler:

http.HandleFunc("GET /hello", func(w http.ResponseWriter, r *http.Request) {
	err := helloHandler(w, r)
 
	if err != nil {
      // 全局错误处理函数
      ErrorHandlerFunc(w, err)
	}
})

这样我们就能集中处理错误。考虑下面的例子:

main.go
// ...
 
// mux.Get("/hello", helloHandler)
func helloHandler(w http.ResponseWriter, r *http.Request) error {
	name := r.URL.Query().Get("name")
 
	if name == "" {
		return httpz.NewHTTPError(http.StatusBadRequest, "name is required")
	}
 
	fmt.Fprintf(w, "hello %s", name)
	return nil
}

当我们访问http://localhost:8080/hello , 这时name为空字符串,你将会看到:{"msg":"name is required"},这是我们默认的错误处理函数 返回的响应。

默认的错误处理函数

// default centrailzed error handling function.
// only the *HTTPError will triger error response.
func DefaultErrHandlerFunc(err error, w http.ResponseWriter) {
	if he, ok := err.(*HTTPError); ok {
		rw := NewHelperRW(w)
		rw.JSON(he.StatusCode, he)
	} else {
		slog.Error(err.Error())
	}
}

请注意,默认的错误处理函数只对*HTTPError类型的error触发响应,其他类型的error 只会打印日志。这样设计的理由是,当用户返回HTTPError时会明确知道该错误会触发响应, 减少重复返回响应的可能。

你也可以自定义自己的全局错误处理函数:

func main() {
	mux := httpz.NewServeMux()
 
	mux.ErrHandlerFunc = func(err error, w http.ResponseWriter) {
      // 已经判断过 err != nil
      http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

这时,所有非nil的error都会触发响应。