Recover in Golang

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:

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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")
}

chevron_right


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:

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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")
}

chevron_right


Output:

RECOVER Error: Author name cannot be nil
Return successfully from the main function

Example 3:

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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")
}

chevron_right


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


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.