Just like try/catch block in exception in languages like Java, C#, etc. are used to catch exception similarly in Go language, recover function is used to handle panic. It is an inbuilt function which is defined under the builtin package of the Go language. The main use of this function is to regain control of a panicking Goroutine. Or in other words, it handles the panicking behavior of the Goroutine.
Syntax:
func recover() interface{}
Important Points:
- Recover function is always called inside the deferred function, not in the normal function. If you call recover function inside the normal function or outside the deferred function, then the recover function does not stop the panicking sequence as shown in Example 1. So, always called recover function inside the deferred function because the deferred function does not stop its execution if the program panic, so the recover function stops the panicking sequence by simply restoring the normal execution of the goroutine and retrieves the error value passed to the call of panic as shown in the Example 2.
- Recover function only work if you call in the same goroutine in which panic occurs. If you call it in a different goroutine, then it will not work as shown in Example 3.
- If you want to find the stack trace, then use the PrintStack function which is defined under Debug package.
Example 1:
// Go program which illustrates // the concept of recover package main import "fmt"
// This function is created to handle // the panic occurs in entry function // but it does not handle the panic // occurred in the entry function // because it called in the normal // function func handlepanic() { if a := recover(); a != nil {
fmt.Println( "RECOVER" , a)
}
} // Function func entry(lang *string, aname *string) { // Normal function
handlepanic()
// When the value of lang
// is nil it will panic
if lang == nil {
panic( "Error: Language cannot be nil" )
}
// When the value of aname
// is nil it will panic
if aname == nil {
panic( "Error: Author name cannot be nil" )
}
fmt.Printf( "Author Language: %s \n Author Name: %s\n" , *lang, *aname)
fmt.Printf( "Return successfully from the entry function" )
} // Main function func main() { A_lang := "GO Language"
entry(&A_lang, nil)
fmt.Printf( "Return successfully from the main function" )
} |
Output:
panic: Error: Author name cannot be nil goroutine 1 [running]: main.entry(0x41a788, 0x0) /tmp/sandbox777592252/prog.go:35 +0x180 main.main() /tmp/sandbox777592252/prog.go:46 +0x40
Example 2:
// Go program which illustrates // the concept of recover package main import ( "fmt"
) // This function handles the panic // occur in entry function // with the help of the recover function func handlepanic() { if a := recover(); a != nil {
fmt.Println( "RECOVER" , a)
}
} // Function func entry(lang *string, aname *string) { // Deferred function
defer handlepanic()
// When the value of lang
// is nil it will panic
if lang == nil {
panic( "Error: Language cannot be nil" )
}
// When the value of aname
// is nil it will panic
if aname == nil {
panic( "Error: Author name cannot be nil" )
}
fmt.Printf( "Author Language: %s \n Author Name: %s\n" , *lang, *aname)
fmt.Printf( "Return successfully from the entry function" )
} // Main function func main() { A_lang := "GO Language"
entry(&A_lang, nil)
fmt.Printf( "Return successfully from the main function" )
} |
Output:
RECOVER Error: Author name cannot be nil Return successfully from the main function
Example 3:
// Go program which illustrates // recover in a goroutine package main import ( "fmt"
"time"
) // For recovery func handlepanic() { if a := recover(); a != nil {
fmt.Println( "RECOVER" , a)
}
} /* Here, this panic is not handled by the recover
function because of the
recover function is not
called in the same
goroutine in which the
panic occurs */
// Function 1 func myfun1() { defer handlepanic()
fmt.Println( "Welcome to Function 1" )
go myfun2()
time .Sleep(10 * time .Second)
} // Function 2 func myfun2() { fmt.Println( "Welcome to Function 2" )
panic( "Panicked!!" )
} // Main function func main() { myfun1()
fmt.Println( "Return successfully from the main function" )
} |
Output:
Welcome to Function 1 Welcome to Function 2 panic: Panicked!! goroutine 6 [running]: main.myfun2() /tmp/sandbox157568972/prog.go:31 +0xa0 created by main.myfun1 /tmp/sandbox157568972/prog.go:24 +0xc0
Article Tags :