2015-04-24 2 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

Одно можно сказать наверняка, что вы не должны проверять 'if err! = Nil' ** после ** вы вызываете' defer res.Body.Close() '... ошибка должна быть первой. – sberry

+0

Нужно ли публиковать все стеки, в начале это просто говорит 'panic: ошибка времени выполнения: неверный адрес памяти или nere pointer dereference [signal 0xb code = 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: Нет проблем. Счастливый суслик! – sberry

Смежные вопросы