How to Recover panic in Golang

Created
Modified

panic

During a typical panic, normal execution stops, all deferred function calls in that goroutine are executed, and the program crashes with a log message.

package main

func main() {

  panic("invalid")
  
}
$ go run main.go
panic: invalid

goroutine 1 [running]:
main.main()
  /data/main.go:5 +0x27
exit status 2

When a panic occurs, all deferred functions are run in reverse order, starting with those of the topmost function on the stack and proceeding up to main, as the program below demonstrates:

package main

import "fmt"

func main() {
  f(2)
}

func f(x int) {
  
  fmt.Printf("f(%d)\n", x+0/x) // panics if x == 0
  defer fmt.Printf("defer %d\n", x)

  f(x - 1)
}
$ go run main.go
f(2)
f(1)
defer 1
defer 2
panic: runtime error: integer divide by zero

goroutine 1 [running]:
main.f(0x4b4268?)
  /data/main.go:12 +0x114
main.f(0x1)
  /data/main.go:14 +0xf6
main.f(0x2)
  /data/main.go:14 +0xf6
main.main()
  /data/main.go:7 +0x1e
exit status 2

Recover

Let's see an example:

package main

import "fmt"

func main() {
  f(2)
}

func f(x int) {

  defer func() {
    if p := recover(); p != nil {
      fmt.Printf("internal error: %v\n", p)
    }
  }()

  fmt.Printf("f(%d)\n", x+0/x) // panics if x == 0
  f(x - 1)
}
$ go run main.go  
f(2)
f(1)
internal error: runtime error: integer divide by zero

Related Tags