英文:
Terminating or aborting an HTTP request
问题
如何通过一些错误消息中止我的API服务?
调用我的服务的链接:
http://creative.test.spoti.io/api/getVastPlayer?add=
{"Json":Json}&host=api0.spoti.io&domain=domain&userAgent=userAgent&mobile=true
要调用我的服务,客户端需要发送一个Json和一些参数。
我想测试一下我得到的参数是否正确,如果不正确,我想发送一个错误消息。
响应应该是一个Json代码{"Result":"Result","Error":"错误消息"}
我尝试过log.fatal
和os.Exit(1)
,它们会停止服务,而不仅仅是停止调用请求。panic
会中止调用,但它会阻止我发送http.ResponseWriter
,而这是我的错误消息。
我读到了关于panic、defer、recover的一些内容,但我不知道如何使用它们来解决这个问题。
return
可以工作:
mobile :=query.Get("mobile")
if mobile=="mobile" {
str:=`{"Resultt":"","Error":"无效的变量"}`
fmt.Fprint(w, str)
fmt.Println("操作不成功!!")
return
}
但我只能在主函数中使用它,因为在其他函数中,它只会退出该函数而不是调用者函数(请求)。
英文:
What's the way to abort my API serving with some error message?
Link to call my service:
http://creative.test.spoti.io/api/getVastPlayer?add=
{"Json":Json}&host=api0.spoti.io&domain=domain&userAgent=userAgent&mobile=true
To call my service the client need to send a Json and some params.
I want to test if the params that I get are correct, if not I want send a error message.
The response should be a Json Code {"Result":"Result","Error":"error message"}
I tried log.fatal
and os.Exit(1)
they stop the service, not just the call request. panic
aborts the call but it prevents me to send a http.ResponseWriter
which is my error message.
I read something about panic, defer, recover but I don't really know how can I use them to solve this problem.
return
works:
mobile :=query.Get("mobile")
if mobile=="mobile" {
str:=`{"Resultt":"","Error":"No valide Var"}`
fmt.Fprint(w, str)
fmt.Println("No successfull Operation!!")
return}
But I can use it just in the main function, because in the other functions it exits just the func not the caller function (request).
答案1
得分: 7
终止处理HTTP请求只需从ServeHTTP()
方法中返回,例如:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// 检查传入的参数
if !ok {
str := `{"Result":"","Error":"无效的变量"}`
fmt.Fprint(w, str)
return
}
// 处理常规API请求
})
panic(http.ListenAndServe(":8080", nil))
注意:
如果API服务的输入参数无效,你应该考虑返回一个HTTP错误代码,而不是默认的200 OK
。你可以使用http.Error()
函数来实现,例如:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// 检查传入的参数
if !ok {
http.Error(w, "无效的输入参数!", http.StatusBadRequest)
return
}
// 处理常规API请求
})
如果你需要在返回错误代码的同时发送JSON数据的更复杂示例:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// 检查传入的参数
if !ok {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
str := `{"Result":"","Error":"无效的变量"}`
fmt.Fprint(w, str)
return
}
// 处理常规API请求
})
示例展示如何传播“返回”
如果错误是在ServeHTTP()
之外检测到的,例如在从ServeHTTP()
调用的函数中检测到的,你必须返回此错误状态,以便ServeHTTP()
可以返回。
假设你有以下自定义类型用于所需参数,并且有一个负责从请求中解码参数的函数:
type params struct {
// 参数字段
}
func decodeParams(r *http.Request) (*params, error) {
p := new(params)
// 解码参数,如果无效,则返回错误:
if !ok {
return nil, errors.New("无效的参数")
}
// 如果一切顺利:
return p, nil
}
使用这些代码:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
p, err := decodeParams(r)
if err != nil {
http.Error(w, "无效的输入参数!", http.StatusBadRequest)
return
}
// 处理常规API请求
})
还可以参考这个相关问题:https://stackoverflow.com/questions/30858823/golang-how-to-return-in-func-from-another-func
英文:
Terminating the serving of an HTTP request is nothing more than to return from the ServeHTTP()
method, e.g.:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// examine incoming params
if !ok {
str := `{"Result":"","Error":"No valide Var"}`
fmt.Fprint(w, str)
return
}
// Do normal API serving
})
panic(http.ListenAndServe(":8080", nil))
Notes:
If the input params of your API service are invalid, you should consider returning an HTTP error code instead of the implied default 200 OK
. For this you can use the http.Error()
function, for example:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// examine incoming params
if !ok {
http.Error(w, `Invalid input params!`, http.StatusBadRequest)
return
}
// Do normal API serving
})
For a more sophisticated example where you send back JSON data along with the error code:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// examine incoming params
if !ok {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
str := `{"Result":"","Error":"No valide Var"}`
fmt.Fprint(w, str)
return
}
// Do normal API serving
})
Example showing how to propagate "returning"
If the error is detected outside of ServeHTTP()
, e.g. in a function that is called from ServeHTTP()
, you have to return this error state so that ServeHTTP()
can return.
Let's assume you have the following custom type for your required parameters and a function which is responsible to decode them from a request:
type params struct {
// fields for your params
}
func decodeParams(r *http.Request) (*params, error) {
p := new(params)
// decode params, if they are invalid, return an error:
if !ok {
return nil, errors.New("Invalid params")
}
// If everything goes well:
return p, nil
}
Using these:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
p, err := decodeParams(r)
if err != nil {
http.Error(w, `Invalid input params!`, http.StatusBadRequest)
return
}
// Do normal API serving
})
Also see this related question: https://stackoverflow.com/questions/30858823/golang-how-to-return-in-func-from-another-func
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论