Golang中如何处理http.Get的错误问题
Golang中如何处理http.Get的错误问题
在以下代码中,如果我输入错误的URL,程序就会发生panic错误。这种情况下,我认为defer received.Body.Close()不会被执行。我的理解正确吗?如果正确,如何确保即使在发生错误的情况下(比如提供错误URL)底层的TCP连接也能被关闭?
package main
import (
"bufio"
"fmt"
"net/http"
)
func main(){
received, err := http.Get("http://gobyexample.com")
if err != nil {
panic(err)
}
defer received.Body.Close()
fmt.Println("status: ", received.Status)
scanner := bufio.NewScanner(received.Body)
for i := 0; scanner.Scan() && i < 5; i++{
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
panic(err)
}
}
另外,当我在goland中使用defer recived.Body.Close()时,它会用黄色高亮显示,提示unhandled error。defer received.Body.Close()有什么问题吗?
如何/在哪里可以查看received.Body.Close()的结果?
更多关于Golang中如何处理http.Get的错误问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我认为你需要在defer中检查received是否为nil,因为http.Get可能会返回错误
defer func() {
if received != nil {
fmt.Println("Body closing...")
received.Body.Close()
}
}()
更多关于Golang中如何处理http.Get的错误问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
received.Body.Close() 不会被执行,因为 panic 会先发生。我认为这段代码是正确的。
你可以使用一个函数作为 defer 的参数。例如
defer func() {
fmt.Println("Running defer...")
received.Body.Close()
}()
好的。那么在这种情况下,即使出现错误,我该如何确保底层的 TCP 连接被关闭?或者在这种情况下我不需要关闭这个 TCP 连接,因为错误的网址不会得到任何响应,也不需要建立 TCP 连接?
以及我如何/在哪里能看到 received.Body.Close() 的结果?
received.Body.Close()
你说得对。如果出现错误,close将不会执行。为了确保即使在出错情况下也能执行,应该在错误检查之前使用defer close。
实际上,当http.Get返回非nil错误时,resp可能仍然不是nil。还需要确保读取响应中的所有数据,以便能够重用连接。
这是在Go中执行HTTP GET请求的正确方式。
received, err := http.Get("http://gobyexample.com")
if received != nil {
defer func() {
_, err = io.Copy(ioutil.Discard, received.Body)
received.Body.Close()
}()
}
if err != nil {
panic(err)
}
你的理解是正确的。当 http.Get() 返回错误时,received 会是 nil,此时调用 defer received.Body.Close() 会导致 panic,因为你在尝试访问 nil 对象的 Body 字段。
以下是修正后的代码:
package main
import (
"bufio"
"fmt"
"net/http"
)
func main() {
received, err := http.Get("http://gobyexample.com")
if err != nil {
fmt.Printf("HTTP请求失败: %v\n", err)
return
}
defer func() {
if err := received.Body.Close(); err != nil {
fmt.Printf("关闭响应体时出错: %v\n", err)
}
}()
fmt.Println("status: ", received.Status)
scanner := bufio.NewScanner(received.Body)
for i := 0; scanner.Scan() && i < 5; i++ {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Printf("读取响应体时出错: %v\n", err)
}
}
关于 defer received.Body.Close() 的黄色高亮警告,这是因为 Close() 方法返回一个 error,而你没有处理这个可能的错误。在 Go 中,忽略错误返回值通常被认为是不好的实践。
要查看 received.Body.Close() 的结果,你可以这样处理:
defer func() {
if closeErr := received.Body.Close(); closeErr != nil {
fmt.Printf("关闭响应体时出错: %v\n", closeErr)
// 或者记录到日志系统
}
}()
更完整的错误处理版本:
package main
import (
"bufio"
"fmt"
"log"
"net/http"
)
func main() {
received, err := http.Get("http://gobyexample.com")
if err != nil {
log.Printf("HTTP请求失败: %v", err)
return
}
defer func() {
if err := received.Body.Close(); err != nil {
log.Printf("关闭响应体时出错: %v", err)
}
}()
fmt.Println("status: ", received.Status)
scanner := bufio.NewScanner(received.Body)
for i := 0; scanner.Scan() && i < 5; i++ {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Printf("读取响应体时出错: %v", err)
}
}
关键改进点:
- 在检查错误后再使用
defer,确保received不是nil - 使用匿名函数处理
Close()的错误返回值 - 使用
log包或适当的错误处理机制而不是直接panic - 确保即使发生错误,TCP 连接也能被正确关闭

