[go] Aborting a program during a network failure

Hi, I am sending a get request to the site in a loop, and as soon as I get the err program it stops working, and further work in the loop does not continue, how do go with exceptions in general? thank

In go, there are no exceptions.

Either a failing function returns an error as part of its return values or if something goes really bad, you get a panic. You can recover from a panic using defer as described in Defer, Panic, and Recover.

To get more help, sou should try to create some minified code that shows your problem.

here is example

func main(){
    for i := 0; i < 10; i++ {

        Simplereq()
	}
}

func Simplereq()  {
var s, _ = url.ParseQuery("name=Golberg&email=mymail+ffggff@mail.com&locale=en&terms_accepted=on")

apiUrl := "https://www.activityinfo.org/signUp"
resp, err := http.PostForm(apiUrl,s)
checkerror(err)

defer resp.Body.Close()

fmt.println(resp.StatusCode)
}

func check error(err error){
    if err!=nil{
    fmt.println(err)
    }
}

I close body (defer rest.Body()) but then I get err ,then app stop work, How can I make sure that the loop is not interrupted with any error? and work continued?

What error do you get?

I have never encountered any issues with defering a Close() call…

if the site is unavailable, I get an error, and the application exits the loop at the time of the request…

Probably the easiest thing to do: do not close the body if there was an error.

if err != nil {
  checkerror(err) // Or just print it
  return
}

Alternatively, you could make checkerror() return a boolean and then use that:

func checkerror(err error) bool {
  if err != nil {
    fmt.Println(err)
    return true
  }
  return false
}

…

if checkerror(err) { return }

PS: It is not a secret that I’m not a fan of gos error handling, but even less I am a friend of those error handling functions. Just handle the error when and where is returned.

but what if i do not need to do a return after error? for now any error breaks the cycle …and app stop…
I get this error, and include check for bool (true false) but I get err

panic: runtime error: index out of range

and my circle stops( in other lang I processed exceptions, and the program continued to work … but here. (

I found a solution on the Internet, it works like, and the cycle is not interrupted

defer func() {
if r := recover(); r != nil {
    log.Println("Recovered in custom function", r)
}
}()

I think you make a very big mistake. You must check your code for issues nor recover from panic. Is not normal to have panics in your program. Panics are very seriously errors and must be recovered just in exceptional cases, otherwise you must see what generate the error and repair (in your particular case an index out of range).

you’re right, but how do I catch this network error?

panic: runtime error: index out of range

Then replace the return with whatever it should do.

Either way, if there was an error returned from http.PostForm(), then resp will be nil, and therefore anything that tries to access its fields will result in a panic.

In the code you have shown us, there is nothing meaningful you could do with resp in case of err != nil.

I have no clue what could produce an OOR panic in the code you have shown us, as there is nothing that access a slice by index and therefore the code known to us can not produce that panic.

You really really rarely do want that. Yes, it is a way to handle errors, but so far I was always able to handle errors in a way that no panic happens at all.

Also this is pretty much the same as doing return right after printing the err value. Since in the code you have shown us so far, everything after checkerror would have resulted in a nil-panic.

after -http.postform () request

but the matter is not even in the resp==nil…, I tried to process these things manually (causes of errors) and did not find anything(, I applied the option with recovery, for me it works

SOmewhere in the code you have not shown to us, there you are doing something that causes the index out of bounds.

Instead of using recover and forget that the issue exist, you should check your code before that, if you are correctly checking all return error values.

1 Like

Hi

@NobbZ is correct, I also highly suspect this isn’t the code which causes the problem. This is just some proof of concept. Your code as presented could not run without changing some errors like fmt.println instead of fmt.Println and check error instead of checkerror.

Then you recieve a panic will a stack trace be shown and the uppermost line shows which line caused the problem. For example by running this

package main

import (
	"fmt"
	"net/http"
	"net/url"
)

func main() {
	for i := 0; i < 10; i++ {

		Simplereq()
	}
}

func Simplereq() {
	var s, _ = url.ParseQuery("name=Golberg&email=mymail+ffggff@mail.com&locale=en&terms_accepted=on")

	apiUrl := "https://www.activityinfo.org/signUp"
	resp, err := http.PostForm(apiUrl, s)
	checkerror(err)

	defer resp.Body.Close()
	panic("Ouch!")
	fmt.Println(resp.StatusCode)
}

func checkerror(err error) {
	if err != nil {
		fmt.Println(err)
	}
}

will result in the following output:

$ go run main.go 
panic: Ouch!

goroutine 1 [running]:
main.Simplereq()
        /Users/xxx/yyy/main.go:24 +0x184
main.main()
        /Users/xxx/yyy/main.go:12 +0x2a
exit status 2

and you can see that the line causing the panic is line 24 in main.go. If the panic is inside a library function you must follow the lines down to see which call is from your side

1 Like

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