1 回答
TA贡献1843条经验 获得超7个赞
上述方法完全没问题,不会像其他语言那样“捕捉”任何东西。try .. catch
匿名函数的主要原因是只编写一次特定于错误的响应。如果您不喜欢这种方法,还有其他方法可以做到这一点。
句柄错误函数
例如,您可以有一个函数来处理/返回错误,以便此代码不会使处理程序混乱:
func handleErr(w http.ResponseWriter, err error, statusCode int) {
log.Printf("statusCode: %d; error: %s", statusCode, err)
w.WriteHeader(statusCode)
bts, err := json.Marshal(struct {
Error string
}{
Error: err.Error(),
})
if err != nil {
_, _ = w.Write([]byte(`{"Error":"error while marshalling error response"`))
}
_, _ = w.Write(bts)
}
然后,处理程序将如下所示:
func FooHandler(w http.ResponseWriter, r *http.Request) {
var1, err := doSomething1()
if err != nil {
handleErr(w, err, http.StatusBadRequest, "some user error msg")
return
}
var2, err := doSomething2()
if err != nil {
handleErr(w, err, http.StatusUnauthorized, "some user error msg")
return
}
var3, err := doSomething3()
if err != nil {
handleErr(w, err, http.StatusInternalServerError, "some user error msg")
return
}
var4, err := doSomething4()
if err != nil {
handleErr(w, err, http.StatusInternalServerError, "some user error msg")
return
}
// do successful response here
}
使用中间件
正如注释中@mkopriva建议的那样,您还可以对处理程序使用包装器:
func handleErr(f func(w http.ResponseWriter, r *http.Request) (int, error)) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
statusCode, err := f(w, r)
if err != nil {
return
}
log.Printf("statusCode: %d; error: %s", statusCode, err)
w.WriteHeader(statusCode)
bts, err := json.Marshal(struct {
Error string
}{
Error: err.Error(),
})
if err != nil {
_, _ = w.Write([]byte(`{"Error":"error while marshalling error response"`))
}
_, _ = w.Write(bts)
}
}
注册处理程序时,它将被包装:
http.Handle("/foo", handleErr(FooHandler))
现在可以返回状态代码和错误:FooHandler
func FooHandler(w http.ResponseWriter, r *http.Request) (int, error) {
var1, err := doSomething1()
if err != nil {
return http.StatusBadRequest, fmt.Error("some error")
}
var2, err := doSomething2()
if err != nil {
return http.StatusUnauthorized, fmt.Error("some error")
}
var3, err := doSomething3()
if err != nil {
return http.StatusInternalServerError, fmt.Error("some error")
}
var4, err := doSomething4()
if err != nil {
return http.StatusInternalServerError, fmt.Error("some error")
}
// do successful response here
return http.StatusOK, nil
}
- 1 回答
- 0 关注
- 84 浏览
添加回答
举报