跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

Golang如何处理网络请求返回错误

首先检查请求发送阶段的错误,如连接超时、DNS解析失败等;再判断HTTP状态码是否为200或预期范围;设置客户端超时避免阻塞;最后读取响应体时处理可能的传输错误,并始终关闭Body。 在Go语言中处理网络请求返回的错误,关键在于正确使用
net/http
包并检查多个可能出错的环节。很多开发者只关注HTTP 状态码 ,却忽略了更底层的连接、超时或DNS解析等错误,这会导致程序稳定性下降。 检查请求发送阶段的错误 调用
http.Do()
或
http.Get()
等方法时,第一个要判断的是是否成功发出请求。这类错误通常与网络连接有关,比如主机不可达、超时、TLS握手失败等。 示例:
resp, err := http.Get("https://example.com") if err != nil { log.Printf("请求失败: %v", err) // 常见错误类型: // - net.OpError: 连接超时、DNS解析失败 // - *url.Error: URL格式问题或底层连接错误 // - tls.CertificateError: 证书验证失败 return } defer resp.Body.Close()
注意:只要
err != nil
,就说明请求未成功完成,此时
resp
可能是nil或部分响应,不能直接使用。 立即学习 “ go语言免费学习笔记(深入) ”; 检查HTTP状态码 即使请求发送成功(无error),服务器仍可能返回非200的状态码,如404、500、401等。这些不属于Go的“错误”,但对业务来说是异常情况。 建议根据实际需求判断状态码: go语言参考手册 中文CHM版 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译 下载
if resp.StatusCode != http.StatusOK { log.Printf("HTTP错误状态: %d", resp.StatusCode) // 可选择将非200视为错误并处理 return fmt.Errorf("unexpected status: %d", resp.StatusCode) }
也可以接受某些范围的状态码,比如允许2xx和3xx:
if resp.StatusCode >= 400 { return fmt.Errorf("bad response: %d", resp.StatusCode) }
设置超时避免阻塞 默认的
http.Client
没有超时限制,可能导致请求长时间挂起。应自定义Client并设置合理的超时时间。
client := &http.Client{ Timeout: 10 * time.Second, // 整个请求的最大耗时 }

resp, err := client.Get("https://www.php.cn/link/c071c86446066d4de2ba1551614a08c8") if err != nil { log.Printf("请求超时或失败: %v", err) return }

更精细的控制可以使用
Transport
设置连接、读写等阶段的超时:
client := &http.Client{ Transport: &http.Transport{ DialContext: (&net.Dialer{ Timeout: 5 * time.Second, KeepAlive: 30 * time.Second, }).DialContext, TLSHandshakeTimeout: 5 * time.Second, ResponseHeaderTimeout: 5 * time.Second, ExpectContinueTimeout: 1 * time.Second, }, Timeout: 15 * time.Second, }
读取响应体时也要处理错误 即使请求成功且状态码正常,读取
resp.Body
时仍可能发生错误,比如网络中断、数据截断等。
body, err := io.ReadAll(resp.Body) if err != nil { log.Printf("读取响应体失败: %v", err) return }
记得始终调用
resp.Body.Close()
释放资源,推荐使用
defer
。 基本上就这些。关键是分清楚不同阶段的错误来源:连接层错误由
http.Do
返回,应用层错误看状态码,传输过程中读取失败单独处理,再加上合理的超时配置,就能写出健壮的HTTP客户端代码。

相关文章