2015-04-24 55 views
0

我學習要去與恐慌錯誤掙扎......它的工作了一段時間,但很快這樣的例外,最終panic: runtime error: invalid memory address or nil pointer dereference圖源「無效的內存地址......」與http.client

的函數只需遍歷代理映射,直到它成功獲取「地址」的內容爲止。它一定不是很習慣,尤其是使用地圖而不是切片和最後的回報,但我希望這不是恐慌粉碎的原因... 如果我省略了一些可能的重要請,讓我知道,我會更新帖子,我只是不想用不必要的信息來氾濫它。代理是一個帶有地圖字段的結構,其中包含用於併發安全讀取/刪除的方法。

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

+2

什麼是確切的錯誤信息,包括行號,什麼行不,在你的代碼對應? – sberry

+3

有一點可以肯定的是,在你調用'defer res.Body.Close()'之後,你不應該檢查'if err!= nil' ** ...錯誤檢查應該是第一位的。 – sberry

+0

是否有必要發佈所有堆棧,在開始時它只是說'恐慌:運行時錯誤:無效的內存地址或零指針解引用[信號0xb代碼= 0x1 addr = 0x0 pc = 0x408762]'然後它跟着一長串其他信息.. – MikeKlemin

回答

4

直到我看到更多的信息,這簡直是基於什麼我可以從您發佈的代碼收集猜測。

呼叫

res.Body.Close() 

應該出現在你檢查錯誤之後,而不是之前。所以改變:

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

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

太簡單了......我的大腦幾乎受損了,我做了幾十種各樣的東西,但是從來沒有想過延遲必須在錯誤檢查後肯定... 非常感謝! – MikeKlemin

+0

@MikeKlemin:沒問題。快樂gophering! – sberry