英文:
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
}
}
在api1
和api2
中,都调用了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)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论