Ogólna koncepcja jest taka, że gdy funkcja (lub metody) ma wielu zwracają wartości jednego będąc error
, błąd powinien być sprawdzane jako pierwsze i kontynuowane, jeśli błąd wynosi nil
. Funkcje powinny zwracać wartości zerowe dla innych (bez błędów) wartości, jeśli istnieje error
. Jeśli funkcja zachowuje się inaczej, powinna być udokumentowana. http.Get()
nie dokumentuje takich odchyleń.
Więc to powinno być traktowane tak:
res, err := http.Get(url)
if err != nil {
log.Printf("Error: %s\n", err)
return
}
defer res.Body.Close()
// Read/work with body
Uwagi:
Jak JimB potwierdza też, jeśli nie- nil
zwracany jest błąd, nawet jeśli odpowiedź nie jest - nil
, nie musimy tego zamykać. W przypadku błędu przekierowania odpowiedź inna niż nil
może zawierać kontekst i dodatkowe informacje o tym, gdzie po przekierowaniu nie powiodło się. Zobacz szczegóły poniżej:
http.Get()
wyróżnieniem ogólnej koncepcji „przez większość czasu”: zwraca nil
odpowiedź, jeśli wystąpi błąd:
return nil, someError
Jednak sprawdzanie client.go
, metoda unexported Client.doFollowingRedirects()
, obecnie linia # 427:
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
}
Więc ze względu na wsteczną kompatybilność problemu może powrócić niebędącą nil
odpowiedź i niebędącą nil
błąd w tym samym czasie, f przekierowanie nie działa.
Z drugiej strony próba wywołania resp.Body.Close()
, jeśli resp
jest nil
spowoduje panikę run-time.
Więc jeśli chcemy, aby zamknąć ciało reakcji w tym przypadku, może wyglądać następująco (może być zamknięty tylko wtedy resp
nie jest 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
}
czyli
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
The dokument nr http.Response
gwarantuje, że Response.Body
nie będzie nil
, nawet jeśli nie ma danych o odpowiedzi:
// 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.
Jeśli kiedykolwiek otrzymasz ciało odpowiedzi wymagające zamknięcia w wyniku błędu, jest to błąd, który należy złożyć. W takim przypadku powinieneś mieć puste noop bliżej ciała, które tylko tam, aby zamknąć, nie panikuj. – JimB
@JimB Tak też myślałem. Dzięki za potwierdzenie. Dokona edycji odpowiedzi. – icza
Poszedłem i podwoiłem sprawdzanie kodu klienta, aw jednym przypadku, gdy błąd przekierowania zwraca odpowiedź, ciało zostało już zamknięte, a połączenie zwolnione. Chociaż to nie boli, nigdy nie powinno być potrzeby "odraczania resp.Body.Close()" po błędzie klienta. – JimB