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?
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.