英文:
Golang, nil in http requests
问题
我正在创建一个Go脚本,从一个API中获取尽可能多的HTTP请求。
当我使用多个goroutine调用worker()时,具体来说是超过200个goroutine时,我在soundcloud.GetUser(i)这一行遇到了空指针引用的错误。
这是我确切遇到的错误:
goroutine 28 [running]:
runtime.panic(0x75fca0, 0x98cf13)
/usr/lib/go/src/pkg/runtime/panic.c:279 +0xf5 www.github.com/Juanvulcano/gosoundcloud%2egit.processAndUnmarshalResponses(0x0, 0x7f1d338e9fd0, 0xc209467a10, 0x780a60, 0xc20809c300, 0x0, 0x0)
/home/maker/go/src/www.github.com/Juanvulcano/gosoundcloud.git/gosoundcloud.go:31 +0x413
www.github.com/Juanvulcano/gosoundcloud%2egit.(*SoundcloudApi).GetUser(0xc208040520, 0x2, 0x7f1d41e81f40, 0x0, 0x0)
/home/maker/go/src/www.github.com/Juanvulcano/gosoundcloud.git/soundcloud.go:295 +0x1b1
main.worker()
/home/maker/go/src/GoBot/GoBot.go:28 +0xdd
created by main.main
/home/maker/go/src/GoBot/GoBot.go:71 +0x55d
这里是我代码的重要部分:
func worker() {
defer wg.Done()
for i := range input {
member, err := soundcloud.GetUser(uint64(i))
if err != nil{
fmt.Println(err)
}
if member != nil {
output <- fmt.Sprint(member.Username)
}
}
}
func main() {
var err error
if err = soundcloud.PasswordCredentialsToken("email", "password"); err != nil {
fmt.Println(err)
os.Exit(1)
}
go func() {
for i := 1; i < 1000; i++ {
input <- i
}
close(input)
wg.Wait()
close(output)
}()
for i := 0; i < 200; i++ {
wg.Add(1)
go worker()
}
printOutput()
}
英文:
I'm creating a Go script to get as many http requests as possible from an API.
I'm getting a nil pointer reference at the line of soundcloud.GetUser(i) when I call worker() with multiple goroutines, more than 200 to be exact.
This is the error I'm getting to be exact.
goroutine 28 [running]:
runtime.panic(0x75fca0, 0x98cf13)
/usr/lib/go/src/pkg/runtime/panic.c:279 +0xf5 www.github.com/Juanvulcano/gosoundcloud%2egit.processAndUnmarshalResponses(0x0, 0x7f1d338e9fd0, 0xc209467a10, 0x780a60, 0xc20809c300, 0x0, 0x0)
/home/maker/go/src/www.github.com/Juanvulcano/gosoundcloud.git/gosoundcloud.go:31 +0x413
www.github.com/Juanvulcano/gosoundcloud%2egit.(*SoundcloudApi).GetUser(0xc208040520, 0x2, 0x7f1d41e81f40, 0x0, 0x0)
/home/maker/go/src/www.github.com/Juanvulcano/gosoundcloud.git/soundcloud.go:295 +0x1b1
main.worker()
/home/maker/go/src/GoBot/GoBot.go:28 +0xdd
created by main.main
/home/maker/go/src/GoBot/GoBot.go:71 +0x55d
Here I'm attaching the important parts of my code.
func worker() {
defer wg.Done()
for i := range input {
member, err := soundcloud.GetUser(uint64(i))
if err != nil{
fmt.Println(err)
}
if member != nil {
output <- fmt.Sprint(member.Username)
}
}
}
func main() {
var err error
if err = soundcloud.PasswordCredentialsToken("email", "password"); err != nil {
fmt.Println(err)
os.Exit(1)
}
go func() {
for i := 1; i < 1000; i++ {
input <- i
}
close(input)
wg.Wait()
close(output)
}()
for i := 0; i < 200; i++ {
wg.Add(1)
go worker()
}
printOutput()
}
答案1
得分: 2
在这个函数中:
func processAndUnmarshalResponses(resp *http.Response, err error, holder interface{}) error {
defer resp.Body.Close()
if err != nil {
return err
}
你在检查错误之前延迟执行了resp.Body.Close()
。如果出现错误,resp
将为nil,对其进行解引用将导致恐慌。请始终先进行错误检查。
英文:
in the function:
func processAndUnmarshalResponses(resp *http.Response, err error, holder interface{}) error {
defer resp.Body.Close()
if err != nil {
return err
}
You are defering resp.Body.Close()
before you check the error. If there is an error, resp
will be nil, and dereferencing it will panic. Always put the error check first.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论