//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
}
May i know how to stop execution rest of the code after called to function RedirectWithMessage
?
Putting return
at the end of that function didn't rest of the code being executed
Im looking the equivalent of Php version of redirect in Golang:
fuunction foo($location){
header(“Location : $location”);
exit();
}
foo("/bar"):
echo "blah"; //this will not be executed
Edited cause of overzealous down-vote.
Yes im fully aware that i can put return
statement after a called to RedirectWithMessage
. I just dont want to clutter my code with return
statement all the place.Instead i just put once inside the function. I just wonder is there any better solution to that? Can i achieve the same behaviour like php code i show?
I was tempted to give you a panic
defer
way and warn you not to use it but then I realize it might be better to change the API.
You can focus the main logic of the function and return the error to the caller, and ask the caller to handle the error the way you want, e.g. redirect, log and so on.
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
}
Note 1: You would possibly want to handle more specified errors, not just dealing with nil and non-nil. In that case, type assertion may be a good idea.
Note 2: You would possibly want to wrap the error. You can try github/pkg/errors
, a good package dealing with erros written by Dave Cheney.
Note 3: It is adviced against to use self
as receiver name, as it is pretty ambiguous.