【问题标题】:How to handle superfluous response.WriteHeader call in order to return 500如何处理多余的 response.WriteHeader 调用以返回 500
【发布时间】:2019-09-07 05:53:04
【问题描述】:

我知道http.ResponseWriterWriteHeader 方法每个HTTP 响应只能调用一次,只能有一个响应状态码,并且只能发送一次标头。这一切都很好。

问题是,如果http.ResponseWriter.Write 返回错误,我应该如何重构我的代码以覆盖201 并返回500?正如您在下面看到的,我故意强制恐慌以查看httprouter.Router.PanicHandler 如何处理它。正如预期的那样,日志显示http: superfluous response.WriteHeader call from ...,响应为201,因为如上所述为时已晚。

package server

import (
    "github.com/julienschmidt/httprouter"
    "log"
    "net/http"
)

func Serve() {
    rtr := httprouter.New()
    rtr.GET("/", home.Welcome)

    handle500(rtr)

    err := http.ListenAndServe(":8080", rtr)
    if err != nil {
        log.Fatalf("server crash")
    }
}

func handle500(r *httprouter.Router) {
    r.PanicHandler = func(res http.ResponseWriter, req *http.Request, err interface{}) {
        res.WriteHeader(http.StatusInternalServerError)
        // http: superfluous response.WriteHeader call from line above
    }
}
package home

import (
    "github.com/julienschmidt/httprouter"
    "net/http"
)

func Welcome(res http.ResponseWriter, _ *http.Request, _ httprouter.Params) {
    // doing a few bits and building the body

    res.Header().Set("Content-Type", "application/json")
    res.WriteHeader(201)

    _, err := res.Write("body goes here")
    if err == nil {  // I am doing this deliberately to test 500
        panic("assume that something has gone wrong with res.Write and an error occurred")
    }
}

【问题讨论】:

  • 要么在写入响应时忽略错误,要么只是从处理程序返回。写入响应是否有错误,那么写入响应时 500 处理程序也会失败。

标签: go


【解决方案1】:

无法“覆盖”状态代码,因为它会立即发送到浏览器。

您正在检查http.ResponseWriter.Write() 的返回值。我不确定这是一个好的策略。如果写入响应失败,那么写入更多也可能会失败。

记录故障似乎更合适,但我希望大多数故障是连接断开和其他不需要操作的错误。

【讨论】:

  • 我发现这个答案正在寻找另一个问题。仅供参考at least as of Go 1.17http.ResponseWriter.Write 隐式调用w.WriteHeader(http.StatusOK),无论这是否是您想要的。因此,您必须手动调用w.WriteHeader任何内容写入响应以手动设置 HTTP 代码。
猜你喜欢
  • 2016-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-18
相关资源
最近更新 更多