如果在调用http.Get(url)时发生错误,是否需要关闭响应对象?

时间:2015-09-28 08:17:23

标签: http go error-handling deferred

在以下代码中,还需要在错误情况下关闭响应主体:

res, err := http.Get(url)

if err != nil {
    log.Printf("Error: %s\n", err)
}

defer res.Body.Close()

1 个答案:

答案 0 :(得分:17)

一般概念是,当函数(或方法)具有多个返回值,其中一个为nil时,应首先检查错误,并且只有在错误为error时才会继续。如果存在res, err := http.Get(url) if err != nil { log.Printf("Error: %s\n", err) return } defer res.Body.Close() // Read/work with body ,则函数应为其他(非错误)值返回零值。如果函数的行为不同,则应记录。 http.Get()没有记录这种偏差。

所以它应该像这样处理:

nil

备注:

正如JimB也确认的那样,如果返回非nil错误,即使回复不是nil,我们也不必关闭它。如果出现重定向错误,非http.Get()响应可能会保留上下文以及有关重定向失败后的位置的更多信息。请参阅以下详细信息:

nil尊重“大部分时间”的一般概念:如果出现错误,它会返回return nil, someError 响应:

Client.doFollowingRedirects()

然而,检查client.go,未导出的方法if redirectFailed { // Special case for Go 1 compatibility: return both the response // and an error if the CheckRedirect function failed. // See https://golang.org/issue/3795 return resp, urlErr } ,当前行#427:

nil

因此,由于向后兼容性问题,如果重定向失败,它可能会同时返回非nil响应和非resp.Body.Close()错误。

另一方面,如果respnil,则尝试拨打resp会导致运行时出现紧急情况。

因此,如果我们想在这种情况下关闭响应正文,它可能看起来像这样(只有在nil不是res, err := http.Get(url) if err != nil { log.Printf("Error: %s\n", err) } if res != nil { defer res.Body.Close() // Read/work with body } 时才能关闭):

res, err := http.Get(url)
if err != nil {
    log.Printf("Error: %s\n", err)
}
if res == nil {
    return
}

defer res.Body.Close()
// Read/work with body

或者:

Response.Body

http.Response的文档保证nil即使没有回复数据也不会// The http Client and Transport guarantee that Body is always // non-nil, even on responses without a body or responses with // a zero-length body.

nil

如果错误不是nil,则您不必关闭非Try This error_reporting(E_ALL); ini_set("display_errors", 1); OR There can be file path not found issue. 响应正文。