Golang中http.ListenAndServe()遇到ERR_EMPTY_RESPONSE错误如何处理

Golang中http.ListenAndServe()遇到ERR_EMPTY_RESPONSE错误如何处理 我正在学习Go语言,并且正在尝试使用http.ListenAndServe()

如果我的某个HTTP处理函数发生panic,浏览器会收到ERR_EMPTY_RESPONSE错误。

现实世界中的HTTP处理是这样实现的吗?

我原以为发生panic时会返回一个HTTP 500“内部服务器错误”。

相关示例:Go by Example: HTTP Servers

2 回复

IIRC 这取决于你的处理程序何时发生恐慌。如果头部信息已经写入,而此时发生恐慌,那么响应就无法再更改为 500 了。

更多关于Golang中http.ListenAndServe()遇到ERR_EMPTY_RESPONSE错误如何处理的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go的HTTP服务器中,当处理函数发生panic时,默认行为确实会导致连接中断,从而产生ERR_EMPTY_RESPONSE错误。这是因为Go的HTTP服务器默认不会从处理函数的panic中恢复。以下是两种常见的处理方式:

1. 使用recover中间件捕获panic

通过自定义中间件包装处理函数,可以在panic发生时恢复并返回500错误:

package main

import (
    "net/http"
)

func panicRecoverMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        defer func() {
            if err := recover(); err != nil {
                w.WriteHeader(http.StatusInternalServerError)
                w.Write([]byte("Internal Server Error"))
            }
        }()
        next.ServeHTTP(w, r)
    })
}

func panicHandler(w http.ResponseWriter, r *http.Request) {
    panic("something went wrong")
}

func main() {
    http.Handle("/panic", panicRecoverMiddleware(http.HandlerFunc(panicHandler)))
    http.ListenAndServe(":8080", nil)
}

2. 使用第三方库

许多Web框架(如Gin、Echo)内置了panic恢复机制。以下是使用Gin框架的示例:

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default() // Default已包含Recovery中间件
    
    r.GET("/panic", func(c *gin.Context) {
        panic("something went wrong")
    })
    
    r.Run(":8080")
}

3. 自定义Server配置

通过创建自定义的http.Server,可以设置ErrorLog来记录panic,但不会自动返回500响应:

package main

import (
    "log"
    "net/http"
    "os"
)

func panicHandler(w http.ResponseWriter, r *http.Request) {
    panic("something went wrong")
}

func main() {
    server := &http.Server{
        Addr: ":8080",
        Handler: http.HandlerFunc(panicHandler),
        ErrorLog: log.New(os.Stderr, "SERVER ERROR: ", log.LstdFlags),
    }
    
    server.ListenAndServe()
}

在生产环境中,通常推荐使用第一种或第二种方法,确保panic被捕获并返回适当的HTTP错误响应,而不是直接断开连接。

回到顶部