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))
    }
}()

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Go语言做Web编程非常方便,并且在开发效率和程序运行效率方面都非常优秀。相比于Java,其最大的优势就是简便易用...
    暗黑破坏球嘿哈阅读 12,946评论 6 66
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,088评论 19 139
  • golang中没有类似Java/C++等面向对象编程语言中的try...catch...finally...语句结...
    CodingTech阅读 7,235评论 1 12
  • fmt格式化字符串 格式:%[旗标][宽度][.精度][arg索引]动词旗标有以下几种:+: 对于数值类型总是输出...
    皮皮v阅读 4,808评论 0 3
  • 对象的创建与销毁 Item 1: 使用static工厂方法,而不是构造函数创建对象:仅仅是创建对象的方法,并非Fa...
    孙小磊阅读 6,271评论 0 3

友情链接更多精彩内容