Some history:
In the early days of Go (before version 1.0) there was no recover()
. A call to panic()
would terminate an application without any way to stop that.
I've found the original discussion that led to adding recover()
, you can read it on the golang-nuts discussion forum:
Proposal for an exception-like mechanism
Beware: the discussion dates back to March, 25, 2010, and it is quite exhausting and long (150 posts through 6 pages).
Eventually it was added on 2010-03-30:
This release contains three language changes:
- The functions
panic
and recover
, intended for reporting and recovering from
failure, have been added to the spec:
http://golang.org/doc/go_spec.html#Handling_panics
In a related change, panicln
is gone, and panic
is now a single-argument
function. Panic and recover are recognized by the gc compilers but the new
behavior is not yet implemented.
Multi-return values and conventions provide a cleaner way to handle errors in Go.
That does not mean however that in some (rare) cases the panic-recover is not useful.
Quoting from the official FAQ: Why does Go not have exceptions?
Go also has a couple of built-in functions to signal and recover from truly exceptional conditions. The recovery mechanism is executed only as part of a function's state being torn down after an error, which is sufficient to handle catastrophe but requires no extra control structures and, when used well, can result in clean error-handling code.
Here is a "real-life" example for when/how it can be useful: quoting from blog post Defer, Panic and Recover:
For a real-world example of panic and recover, see the json package from the Go standard library. It decodes JSON-encoded data with a set of recursive functions. When malformed JSON is encountered, the parser calls panic to unwind the stack to the top-level function call, which recovers from the panic and returns an appropriate error value (see the 'error' and 'unmarshal' methods of the decodeState type in decode.go).
Another example is when you write code (e.g. package) which calls a user-supplied function. You can't trust the provided function that it won't panic. One way is not to deal with it (let the panic wind up), or you may choose to "protect" your code by recovering from those panics. A good example of this is the http server provided in the standard library: you are the one providing functions that the server will call (the handlers or handler functions), and if your handlers panic, the server will recover from those panics and not let your complete application die.
How you should use them:
The convention in the Go libraries is that even when a package uses panic internally, its external API still presents explicit error return values.
Related and useful readings:
http://blog.golang.org/defer-panic-and-recover
http://dave.cheney.net/2012/01/18/why-go-gets-exceptions-right
https://golang.org/doc/faq#exceptions
http://evanfarrer.blogspot.co.uk/2012/05/go-programming-language-has-exceptions.html