Panic and recovering
Go does not have an exception mechanism: you cannot throw exceptions. Instead ituses a panic-and-recover mechanism. It is worth remembering that you should usethis as a last resort, your code will not look, or be, better if it is litteredwith panics. It’s a powerful tool: use it wisely. So, how do you use it? In thewords of the Go Authors [go_blog_panic]:
- Panic
- is a built-in function that stops the ordinary flow of control and beginspanicking. When the function
F
callspanic
, execution ofF
stops, anydeferred functions inF
are executed normally, and thenF
returns to itscaller. To the caller,F
then behaves like a call topanic
. The processcontinues up the stack until all functions in the current goroutine havereturned, at which point the program crashes. Panics can be initiated byinvokingpanic
directly. They can also be caused by runtime errors, such asout-of-bounds array accesses. - Recover
- is a built-in function that regains control of a panicking goroutine.Recover is only useful inside deferred functions. During normal execution,a call to
recover
will returnnil
and have no other effect. If the currentgoroutine is panicking, a call torecover
will capture the value given topanic
and resume normal execution.
This function checks if the function it gets as argument will panic when it isexecuted10:
func Panic(f func()) (b bool) { 1
defer func() { 2
if x := recover(); x != nil {
b = true
}
}()
f() 3
return 4
}
We define a new function Panic
1 that takes a function as an argument (see). It returns true if f
panics when run, else false. Wethen 2 define a defer
function that utilizes recover
. If the currentgoroutine panics, this defer function will notice that. If recover()
returnsnon-nil
we set b
to true. At 3 Execute the function we received as theargument. And finally 4 we return the value of b
. Because b
is a namedreturn parameter.
The following code fragment, shows how we can use this function:
func panicy() {
var a []int
a[3] = 5
}
func main() {
fmt.Println(Panic(panicy))
}
On line 3 the a[3] = 5
triggers a runtime out of bounds error which resultsin a panic. Thus this program will print true
. If we change line 2: vara []int
to var a [4]int
the function panicy
does not panic anymore. Why?