【发布时间】:2018-09-04 02:31:14
【问题描述】:
考虑一下这种情况!
http请求执行成功后,如果执行json编码出错,如何覆盖header代码
func writeResp(w http.ResponseWriter, code int, data interface{}) {
w.Header().Set("Content-Type", "application/json")
//Here I set the status to 201 StatusCreated
w.WriteHeader(code)
s := success{Data: data}
//what if there is an error here and want to override the status to 5xx error
//how to handle error here, panic?, http.Error() is not an option because as we already wrote header to 201, it just prints `http: multiple response.WriteHeader calls`
if err := json.NewEncoder(w).Encode(s); err != nil {
w.Header().Set("Content-Type", "application/json")
//it throws http: multiple response.WriteHeader calls here as we already wrote header above to 201
w.WriteHeader(code)
e := errorResponse{
Code: code,
Error: error,
Description: msg,
}
if err := json.NewEncoder(w).Encode(e); err != nil {
//same how to handle here
}
}
}
我在这里有多个选项,如果我们只是进行致命日志记录,用户将不会确切知道发生了什么,即使我使用w.Write([]byte(msg)) 编写字符串,状态仍然显示201 created,如何以错误代码 5xx 响应
非常感谢任何帮助
【问题讨论】:
-
您必须 不调用 WriteHeader,直到您知道要返回什么状态代码。 绝对 没有 方法可以在调用 WriteHeader 后更改该状态。
-
但是
json.NewEncoder(w).Encode(e)如果 WriteHeader 没有被显式调用,那么在内部进行写入的json.NewEncoder(w).Encode(e)会将状态设置为 StatusOK,这不是我需要的,我想将其设置为 StatusCreated -
阅读文档。仅当您自己没有 WriteHeader 时,内部写入将设置为 200,一旦您知道要发送哪个状态代码,您应该这样做。真的很简单。
-
阅读评论,您所描述的正是我在之前的评论
json.NewEncoder(w).Encode(e) which does a Write internally sets the status to StatusOK if WriteHeader is not called explicitly中所写的内容,假设json.NewEncoder(w).Encode(e)出现故障,我想设置状态码201 以表示成功和5xx 编码失败,你会怎么做? -
不要使用 json.Encoder。使用 json.Marshal。这真的很简单。或者写入中间缓冲区。
标签: http go error-handling net-http