Go处理HTTP异常需检查resp和err双返回值、设超时、分类处理错误:网络层可重试,4xx不重试,5xx有限重试,JSON解析失败需查格式;应封装含context、重试、状态码校验的健壮请求函数。

Go语言中处理HTTP请求异常,核心在于区分错误类型、及时检查返回值、合理设置超时,并避免忽略关键错误。下面从常见错误场景出发,给出实用的处理方式。
检查resp和err双返回值
Go的http.DefaultClient.Do()或http.Get()都返回*http.Response和error。必须同时检查两者——err非空说明网络层失败(如DNS解析失败、连接超时),而err为nil但resp.StatusCode非2xx,属于业务层错误。
- 永远不要只检查
err == nil就认为请求成功 - 即使
err为nil,也要用defer resp.Body.Close()释放资源 - 用
http.StatusText(resp.StatusCode)或直接比对状态码判断语义错误(如404、500)
主动设置超时,避免永久阻塞
默认的http.Client没有超时,可能卡住goroutine。应显式配置Timeout或使用context.WithTimeout。
- 推荐用
context控制:传入带超时的ctx到client.Do(req.WithContext(ctx)) - 可分别设置
Transport的Timeout、IdleConnTimeout等,精细控制各阶段耗时 - 超时错误类型是
*url.Error,其Err字段常为net.OpError,可通过errors.Is(err, context.DeadlineExceeded)准确判断
分类处理不同错误类型
HTTP错误不是单一类型,需根据错误底层原因采取不同策略:
立即学习“go语言免费学习笔记(深入)”;
-
网络层错误(如
connection refused、i/o timeout):通常重试有意义,但要加退避机制 - 客户端错误(4xx):多数是请求问题(参数错、未授权),重试无用,应记录并修正逻辑
- 服务端错误(5xx):可能是临时故障,适合有限重试(如3次,指数退避)
-
JSON解析错误(
json.Unmarshal失败):说明响应体格式异常,需检查Content-Type或服务端返回逻辑
封装健壮的请求函数示例
把重复逻辑(超时、重试、状态码检查、body读取)封装成工具函数,提升复用性和可维护性:
- 接收
context.Context、URL、期望状态码范围(如200–299) - 内置简单重试逻辑(仅针对网络错误和5xx),避免无限循环
- 统一解包
resp.Body,自动处理gzip,返回字节流或结构体 - 错误信息包含原始URL、状态码、底层错误,便于排查










