How to handle error

I have a loop that sends get requests to websites which are placed in a slice, also they are belong to struct type.

I’m going to share last two functions that related to the problem i’ve faced.

First function is checker, takes input in “[]accountinfo” type

func checker(info []accountinfo) {
	var request string
	var statusCode int

	for i := range info {
		request = fmt.Sprintf("https://%s/", info[i].domain)
		statusCode = getRequest(request)

		if statusCode == 200 {
            fmt.Println("that's ok")
		} else {
			fmt.Println(info[i].domain, "not found or content is not valid")
		}

	}
}

And second function is sending request and returning the status code:

func getRequest(url string) int {

	http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}

	resp, err := http.Get(url)
	if err != nil {
		log.Println(err)
	}

	defer resp.Body.Close()

	return resp.StatusCode
}

I’ve got this error:

2019/09/05 17:52:18 Get https://something.com/: dial tcp <ip>:443: connect: connection refused
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x124eebf]

goroutine 1 [running]:
main.getRequest(0xc0000ae0e0, 0x1a, 0x0)
	/Users/ozan/monitoring-development/v2/main.go:147 +0xff
main.checker(0xc000584000, 0x8d, 0x100)
	/Users/ozan/monitoring-development/v2/main.go:110 +0xd3
main.main()
	/Users/ozan/monitoring-development/v2/main.go:67 +0x4dd
exit status 2

People in stackoverflow reminded me that resp is not actually completed hence cannot return status code, in an unpleasant way.
I hope people in here not like the people in stackoverflow. I really don’t understand the point of getting attacked as a newbie by “masters”.

In this case what are the options i have? I think that creating a custom response like, if connection failes return “custom response”
and in the first function. if return == “custom response” then skip that website.
But i don’t know how to do it or is it a proper way…

If you would give some advices in “a pleasant way” i’d be so happy.

1 Like

Checking your code, you are not doing the nil treatment more tha just write to the log and your code continues executing (defer resp.Body.Close() return resp.StatusCode)

I am not a golang “master” but I think you can add returning the error to be more “gopher”. I mean

func getRequest(url string) (int, error) {
	http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}

	if resp, err := http.Get(url);
	if err != nil {
		return -1, err  // Just your special status code
	}

	defer resp.Body.Close()
	return resp.StatusCode, nil
}

And in checker func

func checker(info []accountinfo) {
	var request string
	var statusCode int
	var err error
	
	for i := range info {
		request = fmt.Sprintf("https://%s/", info[i].domain)
		statusCode, err = getRequest(request)

		if err != nil {
		  fmt.Println(err)
		} else {  
			if statusCode == 200 {
				fmt.Println("that's ok")
			} else {
				fmt.Println(info[i].domain, "not found or content is not valid")
			}
		}
	}
}

HTH

2 Likes

Thank you very much, this was really helpful.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.