0

I learning the go and struggling with this panic error... it working for some time, but soon end up with such exception panic: runtime error: invalid memory address or nil pointer dereference

The function simply iterate over map of proxies until it successfully get the content of the "address". It must be not very idiomatic, especially using map instead of slice and the last return, but I hope that is not the reason of panic crush... if I omitted something possible important please, let me know, I will update the post, I just do not want to flood it with unnecessary info. proxies is a struct with map field with methods for concurrent safe read/delete.

func getContent(address string) string {
localProxies := proxies.Get()
for proxy := range localProxies {
    proxyUrl, _ := url.Parse("http://" + proxy)

    transport := http.Transport{
        Dial:  dialTimeout,
        Proxy: http.ProxyURL(proxyUrl),
    }
    httpClient := http.Client{Transport: &transport, Timeout: timeout}
    req, err := http.NewRequest("GET", address, nil)
    if err != nil {
        fmt.Println("Request error: ", err.Error())
    }
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0")
    res, err := httpClient.Do(req)
    defer res.Body.Close()

    if err != nil {
        //          fmt.Println("Broken ", proxy)
        fmt.Println("Response error: ", err.Error())
        proxies.Del(proxy)
        continue
    }
    if res.StatusCode != 200 {
        //          fmt.Println("Status error: ", res.Status)
        proxies.Del(proxy)
        continue
    }
    out, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Println("Read error: ", err.Error())
        proxies.Del(proxy)
        continue
    }
    return string(out)
}
return "error"

}

go version go1.4.2 linux/amd64

MikeKlemin
  • 909
  • 1
  • 8
  • 26
  • 2
    What is the exact error message, including line number, and what line does that correspond to in your code? – sberry Apr 24 '15 at 06:41
  • 3
    One thing for sure is you should not be checking for `if err != nil` **after** you call `defer res.Body.Close()`... the error check should come first. – sberry Apr 24 '15 at 06:43
  • Is it necessary to post all stack, in the beginning it just says `panic: runtime error: invalid memory address or nil pointer dereference [signal 0xb code=0x1 addr=0x0 pc=0x408762]` Then it follows up with a long list of other information.. – MikeKlemin Apr 24 '15 at 06:43
  • 1
    Post the beginning of the stack trace. Near the top it will have the line number, but since that will likely not match your code posted I need to now the line corresponding to that number. – sberry Apr 24 '15 at 06:47

1 Answers1

5

Until I see more information, this is simply a guess based on what I could gather from the code you posted.

The call

res.Body.Close()

should come after your check for error, not before. So change:

 res, err := httpClient.Do(req)
 defer res.Body.Close()
 if err != nil {
     ...
 }

to

 res, err := httpClient.Do(req)
 if err != nil {
     ...
 }
 defer res.Body.Close()
sberry
  • 128,281
  • 18
  • 138
  • 165
  • So simple... My brains got almost damaged, I made dozens of various things, but never thought about that the defer must be certainly after error check... Thank you very much! – MikeKlemin Apr 24 '15 at 06:49
  • @MikeKlemin: No problem. Happy gophering! – sberry Apr 24 '15 at 06:56