找不到Go Lang HTTP连接

I'm a newbie to Go, writing a script to test whether my web-server's are up and mai if not. Everything's working except one niggling issue which is driving me crazy, tried quite a few solutions posted elsewhere.

The issue is when the web server is totally down and does not reply, Go is crashing:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x0 pc=0x40140e]

goroutine 16 [running]:
runtime.panic(0x68b1c0, 0x83bfe2)
        c:/go/src/pkg/runtime/panic.c:279 +0x11f
main.httpGET(0x6f0530, 0x15)
httpcheck.go
:57 +0x32e
main.main()
httpcheck.go
:43 +0x3b

goroutine 19 [finalizer wait]:
runtime.park(0x415bb0, 0x840c38, 0x83eda9)
        c:/go/src/pkg/runtime/proc.c:1369 +0xac
runtime.parkunlock(0x840c38, 0x83eda9)
        c:/go/src/pkg/runtime/proc.c:1385 +0x42
runfinq()
        c:/go/src/pkg/runtime/mgc0.c:2644 +0xdd
runtime.goexit()
        c:/go/src/pkg/runtime/proc.c:1445
exit status 2

Here's what i have till the crash....

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "github.com/sendgrid/sendgrid-go"
    "os"
    "time"
    "net"
)

var finishedWaiting bool
var timeout = time.Duration(2) * time.Second
var httpClient = http.DefaultClient

func main() {
    const url = "http://doesnotexist.com"
    httpGET(url)
    log.Println("main is running")

}

func httpGET(url string) {
    log.Println("httpGet is runnning")

    resp, err := httpClient.Get(url)

    if err != nil && !doesFileExist("down") {

    }

    if resp.StatusCode != 200 && !doesFileExist("down") {
        isDown()

    } else if resp.StatusCode == 200 && doesFileExist("down") {
        log.Println("200 response")
        sendmail("up")
        removeDownFile()

    }
}

func sendmail(status string) {
    sg := sendgrid.NewSendGridClient("user", "pass")
    message := sendgrid.NewMail()
    message.AddTo("admin@website.com")
    message.AddToName("WebBot")

    if status == "down" {
        message.SetSubject("Websites Down")
        message.SetText("Sites may be down")
    } else {
        message.SetSubject("Website Up")
        message.SetText("Sites are back Up")
    }
    message.SetFrom("admin@website.com")
    if r := sg.Send(message); r == nil {
        fmt.Println("Email sent!")
    } else {
        fmt.Println(r)
    }
}

//checks if the file name is present
func doesFileExist(name string) bool {
    if _, err := os.Stat(name); err != nil {
        if os.IsNotExist(err) {
            return false
        }
    }
    return true
}

// write down file
func writeDownFile() {
    contents, _ := ioutil.ReadFile("")
    ioutil.WriteFile("down", contents, 0x777)

}

//remove down file if server is back up
func removeDownFile() {
    os.Remove("down")

}

func sleepForTen() {
    log.Println("sleeping for 10.....")
    time.Sleep(10000 * time.Millisecond)
    finishedWaiting = true
    main()

}

func isDown() {
    if finishedWaiting != true {
        sleepForTen()

    } else {
        writeDownFile()
        log.Println("200 response")
        sendmail("down")
    }
}

A nudge in the right direction would be appreciated, to help me gracefully determine if the connection cant be established at all.

Thanks.

If an error occurs in the get you just continue with the program. No wonder resp will be nil later.

That's ofc only a guess, since we can only guess the line numbers.

You're trying to check resp.StatusCode even if the Get returned an error. The http.Response is not valid in this case, and may be nil, or contain nil pointers, so you cannot use it.

The problem is that you're ignoring the err object. resp is probably nil because of this error, which causes a panic when you try to access resp.StatusCode. I'm not sure what's the point with doesFileExist, but try this :

func httpGET(url string) {
    log.Println("httpGet is runnning")

    resp, err := httpClient.Get(url)

    if err != nil || resp.StatusCode != 200 && !doesFileExist("down") {
        isDown()
    } else if resp.StatusCode == 200 && doesFileExist("down") {
        log.Println("200 response")
        sendmail("up")
        removeDownFile()
    }
}