0

I am new to golang. My program panics after I try to catch an error in the main block after getting location defined. I have read somewhere, adding defer.close() might help, but again the compiler says no such definition exists in your struct Help me resolve it.

type IPInfo struct {

    IP string

    Hostname string

    City string
    Country string

    Loc string
    Org string
    Postal string
}
func main() {
        ip := getLocalIpv4()
        location, err := ForeignIP(ip)
        if err != nil {
            fmt.Println("error bro")
        }

    fmt.Println("ip address of this machine is ", location.IP)
    fmt.Println(" city of this machine is ", location.City)

}

// MyIP provides information about the public IP address of the client.
func MyIP() (*IPInfo, error) {
    return ForeignIP("")
}

// ForeignIP provides information about the given IP address,
// which should be in dotted-quad form.
func ForeignIP(ip string) (*IPInfo, error) {
    if ip != "" {
        ip += "/" + ip
    }
    response, err := http.Get("http://ipinfo.io" + ip + "/json")
    if err != nil {
        return nil, err
    }
    defer response.Body.Close()

    contents, err := ioutil.ReadAll(response.Body)
    if err != nil {
        return nil, err
    }
    var ipinfo IPInfo
    if err := json.Unmarshal(contents, &ipinfo); err != nil {
        return nil, err
    }
    return &ipinfo, nil
}

// retrieves ip address of local machine
func getLocalIpv4() string {
    host, _ := os.Hostname()
    addrs, _ := net.LookupIP(host)
    for _, addr := range addrs {
        if ipv4 := addr.To4(); ipv4 != nil {
            return fmt.Sprintf("%s", ipv4)
        }
    }
    return "localhost"
}

1 Answer 1

1

Your ForeignIP() returns *IPInfo which is a struct of pointer type but you're getting error from this line of code response, err := http.Get("http://ipinfo.io" + ip + "/json") which is failed due to below error:

dial tcp: lookup ipinfo.io172.16.11.115: no such host.

Then you return nil over there like.

   if err != nil {
            return nil , err
   }

And you access the value of nil as:

location, err := ForeignIP(ip)
fmt.Println("ip address of this machine is ", location.IP)
fmt.Println(" city of this machine is ", location.City)

So nil value has not any IP or City variable that is why it panic. So you need to return struct which is of pointer type then you can access the variable IP and City from location response, here I'm modifying the code.

func ForeignIP(ip string) (*IPInfo, error) {
    var ipinfo IPInfo
    if ip != "" {
        ip += "/" + ip
    }
    response, err := http.Get("http://ipinfo.io" + ip + "/json")
    if err != nil {
        return &ipinfo , err
    }

    defer response.Body.Close()

    contents, err := ioutil.ReadAll(response.Body)
    if err != nil {
        return &ipinfo, err
    }

    if err := json.Unmarshal(contents, &ipinfo); err != nil {
        return &ipinfo, err
    }
    return &ipinfo, nil
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.