在写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))
}
}()
改动之后,果然不再出现警告
网友评论