Golang恐慌:运行时错误:无效的内存地址或无指针取消引用

时间:2017-12-27 20:38:33

标签: go

我是golang的新手,它可能是一个非常基本的东西,但我似乎无法找到解决方案。

请求返回json,就像这样。

{"uuid":"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a22","name":"core1","owner":"systems","description":"new","creation_date":"2017-06-10T14:20:00Z"}

这是gocode。

package main

import (
    "crypto/tls"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
)

type Project struct {
    Uuid          string `json:"uuid"`
    Name          string `json:"name"`
    Owner         string `json:"owner"`
    Description   string `json:"description"`
    Creation_date string `json:"creation_date"`
}

func main() {
    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    }
    client := &http.Client{Transport: tr}
    req, err := http.NewRequest("GET", "https://localhost:4443/project/core1", nil)
    req.SetBasicAuth("rohit", "rohit")
    resp, err := client.Do(req)
    if err != nil {
        fmt.Printf("server not responding %s", err.Error())
    }
    var p Project

    b, err := ioutil.ReadAll(resp.Body)
    defer resp.Body.Close()
    err = json.Unmarshal(b, &p)
    if err != nil {
        fmt.Printf("Test case failed with error %s", err.Error())
    }
    if resp.StatusCode != 403 {
        fmt.Printf("failed %s", err.Error())
    }
}

运行后我收到此错误

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x40142f]

goroutine 1 [running]:
panic(0x60c860, 0xc42000c130)
    /usr/local/go/src/runtime/panic.go:500 +0x1a1
main.main()
    /home/rohitk/Go_projects/src/first_program/test/main.go:41 +0x42f
exit status 2

我检查过并且响应机构有正确的数据。 有人可以建议这里发生了什么。谢谢!

2 个答案:

答案 0 :(得分:2)

正如评论者所提到的,您的代码只是打印错误,而不是通过改变程序的行为来处理

resp, err := client.Do(req)
if err != nil {
    fmt.Printf("server not responding %s", err.Error())
}
// ...

b, err := ioutil.ReadAll(resp.Body)

在上面的代码段中,如果出现错误,则会打印出来;然而,流量控制仍然照常进行,即使" resp"对象可能无效(例如nil)。

当库程序遇到错误时,您通常应该立即将其返回而不需要任何进一步的操作。对于最终用户应用程序,通常应显示错误(通常在stderr流上)并退出程序(通常使用非零退出代码)。例如:

resp, err := client.Do(req)
if err != nil {
    fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
    os.Exit(1) // Exit the program if we didn't get a response.
}
// ...

b, err := ioutil.ReadAll(resp.Body)

答案 1 :(得分:0)

我只是看到这个问题,我只是想贡献自己的力量。 正如@maerics所提到的那样,如注释者所提到的那样,您的代码只是打印错误,而不是通过更改程序的行为来处理它们。我的观察还发现,您有两个地方正在打印错误而不处理错误。

if err != nil { fmt.Printf("server not responding %s", err.Error()) }

应该是:

if err != nil { fmt.Printf("server not responding %s", err.Error()) return // the return statement here helps to handle the error }

第二个也是:

if err != nil { fmt.Printf("Test case failed with error %s", err.Error()) }

它应该是:

if err != nil { fmt.Printf("Test case failed with error %s", err.Error()) return // the return statement here helps to handle the error }