Recover in Golang

17 Sep, 2019
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 recoverpackage 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// functionfunc handlepanic() {      if a := recover(); a != nil {        fmt.Println("RECOVER", a)    }}  // Functionfunc 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 functionfunc 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 recoverpackage main  import (    "fmt")  // This function handles the panic// occur in entry function// with the help of the recover functionfunc handlepanic() {      if a := recover(); a != nil {              fmt.Println("RECOVER", a)    }}  // Functionfunc 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 functionfunc 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 goroutinepackage main  import (    "fmt"    "time")  // For recoveryfunc 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 1func myfun1() {      defer handlepanic()    fmt.Println("Welcome to Function 1")    go myfun2()    time.Sleep(10 * time.Second)}  // Function 2func myfun2() {      fmt.Println("Welcome to Function 2")    panic("Panicked!!")}  // Main functionfunc 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

Golang
Go Language
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
strings.Replace() Function in Golang With Examples
Arrays in Go
Golang Maps
How to Split a String in Golang?
Interfaces in Golang
Slices in Golang
Different Ways to Find the Type of Variable in Golang
How to Parse JSON in Golang?
How to Trim a String in Golang?
How to convert a string in lower case in Golang?