10

so my case is quite complex but for asking question in clean and clear context I am using simple for loop that initiate from 0 and goes upto 10. Now what I am trying to do is when i becomes equal to 2 program will consider this as panic. It will go to recover state using defer and then after recovery loop will resume.

So desired output should be something like that:

0
1
panic occured: got 2
3
4
.
.
.
.
.
10

Actual output I am getting

0
1
panic occured got:  got 2

Code block:

package main

import "fmt"

func main() {
    goFrom1To10()
}

func goFrom1To10() {
    defer recovery()
    for i := 0; i <= 10; i++ {

        if i == 2 {
            panic("got 2")

        }
        fmt.Println(i)
    }

}

func recovery() {
    if r := recover(); r != nil {
        fmt.Println("panic occured: ", r)
    }

}

Can this be achievable in go like when panic occur somehow we can recover and complete our loop?

Ahsan Naseem
  • 1,046
  • 1
  • 19
  • 38

1 Answers1

22

You can do that if the body of the loop is executed as a function, either anonymous or a named one, and in that function you use a deferred function to recover.

Here's how it looks like with anonymous functions:

func goFrom1To10() {
    for i := 0; i <= 10; i++ {
        func() {
            defer func() {
                if r := recover(); r != nil {
                    fmt.Println("panic occured: ", r)
                }
            }()

            if i == 2 {
                panic("got 2")
            }
            fmt.Println(i)
        }()
    }
}

Output (try it on the Go Playground):

0
1
panic occured:  got 2
3
4
5
6
7
8
9
10

It's nicer and easier to understand if you move it to a named function:

func goFrom1To10() {
    for i := 0; i <= 10; i++ {
        task(i)
    }
}

func task(i int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("panic occured: ", r)
        }
    }()

    if i == 2 {
        panic("got 2")
    }
    fmt.Println(i)
}

Output is the same. Try this one on the Go Playground.

icza
  • 389,944
  • 63
  • 907
  • 827
  • thanks @icza for your answer and explanation, your logic and solution help me such cases create separate function for panic and recovery. Again thanks! – Ahsan Naseem Jun 30 '18 at 08:57
  • @icza, I could not understand the logic behind it. Please can you explain , why it's happening by shifting recovery calls near to panic or something like this. ? – Siyaram Malav May 31 '20 at 10:48