How to do error http error handling in Go language

huangapple go评论79阅读模式
英文:

How to do error http error handling in Go language

问题

我对Go语言中的错误处理也感到有些困惑。我已经阅读了很多关于错误处理的帖子,但仍然无法将它们应用到我的代码结构中。我是Go的新手,请帮助我。

有一个主函数处理两个API:api1和api2。

func main() {
    http.HandleFunc("/offers", api1)
    http.HandleFunc("/getOffersList", api2)
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

func api1(w http.ResponseWriter, req *http.Request) {
    validateRequestHeader(w, req, "GET")
    // 这里是代码...
}

func api2(w http.ResponseWriter, req *http.Request) {
    validateRequestHeader(w, req, "POST")
    // 这里是代码...
}

func validateRequestHeader(w http.ResponseWriter, req *http.Request, allowedMethod string) {
    // 允许跨域AJAX请求
    w.Header().Set("Content-Type", "application/json")
    if origin := req.Header.Get("Origin"); origin != "" {
        w.Header().Set("Access-Control-Allow-Origin", origin)
        w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
        w.Header().Set("Access-Control-Allow-Headers",
            "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
    }
    // 如果是预检请求(Preflighted OPTIONS request),则在此停止处理
    if req.Method == "OPTIONS" {
        return
    }
    if req.Method != allowedMethod {
        response := "Only " + allowedMethod + " requests are allowed"
        http.Error(w, response, http.StatusMethodNotAllowed)
        return
    }
}

api1api2中,都调用了validateRequestHeader函数。如果这个函数返回true,那么在api1/api2中的进一步代码就会被执行,而我不希望这样。应该如何处理这个问题?

if req.Method != allowedMethod {
    response := "Only " + allowedMethod + " requests are allowed"
    http.Error(w, response, http.StatusMethodNotAllowed)
    return
}

如果req.Method不等于allowedMethod,则会返回一个错误响应,并提前结束请求处理。

英文:

I am little confused on how error handling should be done in go. I have read so many posts about it but still am not able to apply them on my structure of code. I am new to go so please help.

There is a main function which handles two apis: api1 and api2

func main() {
	http.HandleFunc("/offers", api1)
	http.HandleFunc("/getOffersList", api2)
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}


func api1(w http.ResponseWriter, req *http.Request) {
	validateRequestHeader(w, req, "GET")
    // code here....
}

func api2(w http.ResponseWriter, req *http.Request) {
	validateRequestHeader(w, req, "POST")
    //code here....
}

func validateRequestHeader(w http.ResponseWriter, req *http.Request, allowedMethod string) {
	// allow cross domain AJAX requests
	w.Header().Set("Content-Type", "application/json")
	if origin := req.Header.Get("Origin"); origin != "" {
		w.Header().Set("Access-Control-Allow-Origin", origin)
		w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
		w.Header().Set("Access-Control-Allow-Headers",
			"Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
	}
	// Stop here if its Preflighted OPTIONS request
	if req.Method == "OPTIONS" {
		return
	}
	if req.Method != allowedMethod {
		response := "Only " + allowedMethod + " requests are allowed"
		http.Error(w, response, http.StatusMethodNotAllowed)
		return
	}
}

In both api1 and api2 , function validateRequestHeader is getting called. If this gets true, then in the api1/api2 further code is getting executed which I do not want. How it should be handled?

if req.Method != allowedMethod {
        response := "Only " + allowedMethod + " requests are allowed"
        http.Error(w, response, http.StatusMethodNotAllowed)
        return
    }

答案1

得分: 14

这篇博客文章详细介绍了如何链接多个处理函数,这正是你应该做的。这样,你可以有一个验证处理程序、一个日志处理程序、一个授权处理程序等等,然后将它们链接在一起。

基本上,你可以这样做:

func validator(next http.Handler) http.Handler {
    fn := func(w http.ResponseWriter, req *http.Request) {
        if isRequestValid(req) {
            // 将有效的请求传递给下一个处理程序
            next.ServeHTTP(w, req)
        } else {
            // 否则,返回错误响应
            http.Error(w, "Bad request - Go away!", 400)
        }
    }
    return http.HandlerFunc(fn)
}

func api1() http.Handler {
    fn := func(w http.ResponseWriter, req *http.Request) {
        // api 1 的代码
    }
    return http.HandlerFunc(fn)
}

func api2() http.Handler {
    fn := func(w http.ResponseWriter, req *http.Request) {
        // api 2 的代码
    }
    return http.HandlerFunc(fn)
}

然后在你的 main 函数中将它们链接起来。

func main() {
    http.Handler("/offers", validate(api1()))
    http.Handler("/getOffersList", validate(api2()))
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}
英文:

This blog post goes into some details on how to chain multiple handler functions, which is what you should be doing. That way, you can have a validation handler, a logging handler, an authorization handler, etc etc. and just chain them together.

Essentially

func validator(next http.Handler) http.Handler {
    fn := func(w http.ResponseWriter, req *http.Request) {
            if isRequestValid(req) {
                // a valid request is passed on to next handler
                next.ServeHTTP(w, req)
            } else {
                // otherwise, respond with an error
                http.Error(w, "Bad request - Go away!", 400)
            }
    }
    return http.HandlerFunc(fn)
}

func api1() http.Handler {
    fn := func(w http.ResponseWriter, req *http.Request) {
            // api 1 code
    }
    return http.HandlerFunc(fn)
}

func api2() http.Handler {
    fn := func(w http.ResponseWriter, req *http.Request) {
            // api 2 code
    }
    return http.HandlerFunc(fn)
}

And then chain them up in your main function.

func main() {
    http.Handler("/offers", validate(api1()))
    http.Handler("/getOffersList", validate(api2()))
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

huangapple
  • 本文由 发表于 2017年5月5日 16:07:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/43799703.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定