Go警告信息:http: multiple response.WriteHeader calls

在写Response时,我加入了一个defer,当捕捉到panic时,写入status code=500:

defer func(){
    data := recover()
    error_str := "We encountered an internal error"
    if err, ok := data.(string); !ok {
        error_str = err
    }
    fmt.Println("Internal error:", data)
    w.WriteHeader(http.StatusInternalServerError)
    w.Write([]byte(error_str))
}()

但这个写法是错把defer+recover当成只有只有panic发生时才会执行的东西了。实际上,defer func会在函数尾部执行,这样WriteHeader就被执行了两次。
根据godoc,WriteHeader在不手动调用时,首次Write将会写入200,如果手动调用,通常都是写入500. 要想不引起警告,WriteHeader要在Write()执行之前调用,并且不能多次调用。

此外,正确的处理方式是在defer中判断是否是panic导致了defer调用:

defer func(){
    err := recover()
    if err != nil {
        fmt.Println("Internal error:", err)
        var err_str string
        var ok bool
        if err_str, ok = err.(string); !ok {
            err_str = "We encountered an internal error"
        }
        w.WriteHeader(http.StatusInternalServerError)
        w.Write([]byte(err_str))
    }
}()

改动之后,果然不再出现警告

你可能感兴趣的:(Go警告信息:http: multiple response.WriteHeader calls)