错误处理 anon 函数的最佳做法

我正在处理一些大型Go项目,但我想问一个关于错误处理最佳实践的问题。据我所知,错误不应该被隐藏/“捕获”,但我可能是错的。


在我正在研究的许多项目中,我在http处理程序中看到了很多这样的情况。有时大约有 8 个函数调用


func FooHandler(w http.ResponseWriter, r *http.Request) {

    if err := func() error {

        var1, err := doSomething1()

        if err != nil {

             return fmt.Error("some error")

        }


        var2, err := doSomething2()

        if err != nil {

             return fmt.Error("some error")

        }


        var3, err := doSomething3()

        if err != nil {

             return fmt.Error("some error")

        }


        var4, err := doSomething4()

        if err != nil {

             return fmt.Error("some error")

        }

    }(); err != nil {

        // build error response here

    }

    // do successful response here

}

这似乎就像在围棋中做尝试/捕捉,但最好知道这是否被接受的做法。另一种方法是使用函数来编写错误响应,但会重复代码。if err != nil


翻过高山走不出你
浏览 85回答 1
1回答

蓝山帝景

上述方法完全没问题,不会像其他语言那样“捕捉”任何东西。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))现在可以返回状态代码和错误:FooHandlerfunc 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}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go