当json编码

时间:2018-03-26 02:28:18

标签: http go error-handling net-http

考虑这种情况!

成功执行http请求后,如果执行json编码时出错,如何覆盖标题代码

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创建,如何回复错误代码5xx

非常感谢任何帮助

1 个答案:

答案 0 :(得分:0)

首先,编码时似乎不太可能出现错误。

请参阅此问题,了解Marshal失败的原因:

What input will cause golang's json.Marshal to return an error?

另一个潜在的错误原因是实际将数据写入响应流时会出现问题,但在这种情况下,您也无法编写自定义错误。

回到你的问题,如果你担心编码对象可能会失败,你可以先对数据进行编组(检查错误),然后只编写201状态代码(和编码数据),如果编组成功的话。 / p>

稍微修改你的例子:

s := success{Data: data}
jsonData, err := json.Marshal(s)
if err != nil {
    // write your error to w, then return
}
w.WriteHeader(code)
w.Header().Set("Content-Type", "application/json")
w.Write(jsonData)

现在,最后write也会抛出错误。

但如果发生这种情况,在编写自定义错误时也会失败,因此在这种情况下,您最好在服务器端记录(或将错误发送到跟踪器,如New Relic等)。