重定向后停止代码执行

时间:2018-02-05 10:22:15

标签: go

//main.go
func (self *GoodsController) GoodsEditGet(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    tmpID, ok := vars["id"]
    sess := session.Instance(w, r)

    if !ok {
        tpl.Error("Invalid goods id")
    }

    id, _ := strconv.ParseInt(tmpID, 10, 64)

    goods, err := service.NewGoodsService(w, r).GetGoodsDetail(id)

    if err != nil {
        //This utility function will not stop the rest of the code being executed
        util.RedirectWithMessage(w, r, err.Error(), "/system/inventory/goods")
    }

    //This line will be executed even though the above line producing error
    goodsUom, err := service.NewGoodsService(w, r).GetGoodsUom(id)

    if err != nil {
        util.RedirectWithMessage(w, r, err.Error(), "/system/inventory/goods")
    }

}

//package utility
func RedirectWithMessage(w http.ResponseWriter, r *http.Request, errMsg string, redirect string) {
    sess := session.Instance(w, r)
    sess.FlashError(errMsg)
    sess.FlashForm(r)
    sess.Save(r, w)
    http.Redirect(w, r, redirect, http.StatusFound)
    return
}

我是否知道如何在调用函数RedirectWithMessage后停止执行其余的代码?

return放在该函数的末尾并没有执行其余的代码

我在Golang看起来相当于Php版本的重定向:

fuunction foo($location){
  header(“Location : $location”);
  exit();
}

 foo("/bar"):
 echo "blah"; //this will not be executed

已编辑导致过度投票的原因。

是的,我完全清楚我可以在拨打return后发出RedirectWithMessage声明。我只是不想用return语句将我的代码混乱到所有地方。相反,我只是把它放在函数内部。 我只是想知道有更好的解决方案吗?我可以实现像我显示的PHP代码一样的行为吗?

1 个答案:

答案 0 :(得分:0)

我很想给你一个panic defer方式,并警告你不要使用它,但后来我意识到改变API可能会更好。

您可以聚焦函数的主要逻辑并将错误返回给调用者,并要求调用者以您希望的方式处理错误,例如:重定向,记录等。

func (self *GoodsController) GoodsEditGet(w http.ResponseWriter, r *http.Request) {
    err:=self.goodsEditGet(w,r)
    if err!=nil { //Note 1
        util.RedirectWithMessage(w, r, err.Error(), "/system/inventory/goods")
    }
}

func (self *GoodsController) goodsEditGet(w http.ResponsWriter, r *http.Request) {
    vars := mux.Vars(r)
    tmpID, ok := vars["id"]
    sess := session.Instance(w, r)

    if !ok {
        tpl.Error("Invalid goods id")
    }

    id, _ := strconv.ParseInt(tmpID, 10, 64)

    goods, err := service.NewGoodsService(w, r).GetGoodsDetail(id)

    if err != nil {
        //This utility function will not stop the rest of the code being executed
        return err //Note 2
    }

    goodsUom, err := service.NewGoodsService(w, r).GetGoodsUom(id)

    if err != nil {
        return err
    }
    return nil
}

注1:您可能希望处理更多指定的错误,而不仅仅是处理nil和非nil。在这种情况下,类型断言可能是个好主意。

注2:您可能想要包装错误。你可以尝试github/pkg/errors,这是一个处理由Dave Cheney写的错误的好方法。

注意3:建议不要使用self作为接收者名称,因为它非常模糊。