Go net/http请求返回非nil err的场景及相关技术疑问
关于Go net/http客户端处理HTTP状态码与错误返回的问题
核心问题解答
- 400、401这类状态码会让
err非nil吗?
不会。只要客户端成功与服务器建立连接,并且收到了服务器返回的合法HTTP响应(无论状态码是2xx成功、4xx客户端错误还是5xx服务端错误),client.Do(req)返回的err都会是nil。业务层面的成功与否,需要你通过检查resp.StatusCode来判断。
比如你的示例代码中,请求https://httpbin.org/status/401会得到resp.StatusCode = 401,但err是nil,代码会继续执行到读取响应体的部分。
- 哪些HTTP状态码会触发非nil的
err?
没有任何HTTP状态码会触发client.Do返回非nil的err。err非nil的场景是请求本身无法完成,比如:
- 网络连接失败(断网、服务器不可达)
- DNS解析失败
- 请求超时
- TLS握手失败
- 服务器返回的不是合法的HTTP响应格式
所有2xx、4xx、5xx范围内的状态码都属于标准HTTP响应,此时err必然为nil,业务错误需要自行通过状态码判断处理。
- 官方文档查阅位置
可以通过以下方式查看官方说明:
- 本地执行命令:
godoc net/http Client.Do,查看Client.Do方法的详细文档,里面明确说明了返回错误的场景。 - 查看Go标准库
net/http包中Response结构体的文档,里面也提到了状态码的处理逻辑。
代码示例补充优化
你的示例代码中,当请求返回401这类业务错误时,client.Do不会返回错误,代码会继续执行。如果需要处理这类情况,可以在获取resp后添加状态码校验:
resp, err := client.Do(req) if err != nil { fmt.Println("Error making API call:", err) return } defer resp.Body.Close() // 校验状态码是否为成功范围 if resp.StatusCode < 200 || resp.StatusCode >= 300 { fmt.Printf("Request failed with status code: %d\n", resp.StatusCode) // 这里可以添加自定义错误处理逻辑,比如读取错误响应体、返回业务错误等 return }
内容的提问来源于stack exchange,提问作者Rake Rame
相关产品推荐
相关产品推荐

