Golang REST API 错误处理与解决方案

Golang REST API 错误处理与解决方案 你好,

当我尝试从 Postman 调用 API 时,遇到了 socket hang up 错误。 我正在尝试调用本地的 Go API。 导致 socket hang up 错误的原因可能是什么?

screenshot_postman

3 回复

你能展示一下代码或者提供一个代码链接,让我们看看吗?否则,仅凭这张截图,我最好的猜测是,可能是 Postman 在等待 Go API 响应时超时了。

更多关于Golang REST API 错误处理与解决方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


调用本地主机 Go API

你是想从在线的 Postman 调用 localhost 吗?我认为这是不可能的。API 服务器必须能从互联网访问。例如 http://123.45.67.89:3000/book

示例:https://api3.go4webdev.org/tsk/all

socket hang up 错误通常发生在 HTTP 连接意外中断时。在 Go 的 REST API 中,常见原因包括:

  1. 服务器超时设置过短 - 处理请求时间超过服务器读写超时
  2. 客户端提前关闭连接 - Postman 或客户端设置了较短的超时
  3. 服务器 panic 未恢复 - 处理程序崩溃导致连接中断
  4. 网络问题 - 防火墙或代理中断连接

以下是一个可能导致此问题的示例和修复方案:

// 有问题的代码 - 超时设置过短
func main() {
    http.HandleFunc("/api/data", func(w http.ResponseWriter, r *http.Request) {
        // 模拟长时间处理
        time.Sleep(30 * time.Second) // 超过服务器默认超时
        w.Write([]byte("Data processed"))
    })

    server := &http.Server{
        Addr: ":8080",
        // 默认超时时间较短
    }
    
    server.ListenAndServe()
}

修复方案:

func main() {
    http.HandleFunc("/api/data", func(w http.ResponseWriter, r *http.Request) {
        // 添加超时上下文
        ctx, cancel := context.WithTimeout(r.Context(), 25*time.Second)
        defer cancel()
        
        // 在通道中处理长时间任务
        done := make(chan bool)
        go func() {
            time.Sleep(20 * time.Second) // 长时间任务
            w.Write([]byte("Data processed"))
            done <- true
        }()
        
        select {
        case <-done:
            return
        case <-ctx.Done():
            http.Error(w, "Request timeout", http.StatusRequestTimeout)
            return
        }
    })

    server := &http.Server{
        Addr: ":8080",
        ReadTimeout:  15 * time.Second,
        WriteTimeout: 15 * time.Second,
        IdleTimeout:  60 * time.Second,
    }
    
    // 添加 panic 恢复
    http.HandleFunc("/api/safe", panicRecovery(handleData))
    
    log.Fatal(server.ListenAndServe())
}

// panic 恢复中间件
func panicRecovery(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        defer func() {
            if err := recover(); err != nil {
                log.Printf("Recovered from panic: %v", err)
                http.Error(w, "Internal server error", http.StatusInternalServerError)
            }
        }()
        next(w, r)
    }
}

func handleData(w http.ResponseWriter, r *http.Request) {
    // 业务逻辑
}

调试步骤:

  1. 检查服务器日志是否有 panic 或错误
  2. 使用 curl -v 查看详细连接信息
  3. 增加服务器超时设置
  4. 确保处理程序有 panic 恢复机制
  5. 检查防火墙和代理设置

如果问题仍然存在,请提供服务器端日志和完整的处理程序代码。

回到顶部