With the following code, if no file argument is given, a panic is thrown for line 9 panic: runtime error: index out of range
as expected.
How can I 'catch' this panic and handle it when directly when passing something to it (os.Args[1]
) that causes the panic? Much like try/catch in PHP or try/except in Python.
I've had a search here on StackOverflow but I've not found anything that answers this as such.
package main import ( "fmt" "os" ) func main() { file, err := os.Open(os.Args[1]) if err != nil { fmt.Println("Could not open file") } fmt.Printf("%s", file) }
Recover is a function provided by Go which takes control of a panicking goroutine. recover() can only be used inside deferred functions. If you call recover() during normal flow, it will simply return nil . However, if a goroutine is panicking, recover() will capture the panic value.
A panicking program can recover with the builtin recover() function: The recover function allows a program to manage behavior of a panicking goroutine. Suppose a function G defers a function D that calls recover and a panic occurs in a function on the same goroutine in which G is executing.
Don't use panic for normal error handling. Use error and multiple return values. See https://golang.org/doc/effective_go.html#errors.
A panic is an exception in Go A panic stops the normal execution of a goroutine: When a program panics, it immediately starts to unwind the call stack. This continues until the program crashes and prints a stack trace, or until the built-in recover function is called.
A panicking program can recover with the builtin recover()
function:
The
recover
function allows a program to manage behavior of a panicking goroutine. Suppose a functionG
defers a functionD
that callsrecover
and a panic occurs in a function on the same goroutine in whichG
is executing. When the running of deferred functions reachesD
, the return value ofD
's call torecover
will be the value passed to the call ofpanic
. IfD
returns normally, without starting a newpanic
, the panicking sequence stops. In that case, the state of functions called betweenG
and the call topanic
is discarded, and normal execution resumes. Any functions deferred byG
beforeD
are then run andG
's execution terminates by returning to its caller.The return value of recover is nil if any of the following conditions holds:
panic
's argument wasnil
;- the goroutine is not panicking;
recover
was not called directly by a deferred function.
Here is an example of how to use this:
// access buf[i] and return an error if that fails. func PanicExample(buf []int, i int) (x int, err error) { defer func() { // recover from panic if one occured. Set err to nil otherwise. if (recover() != nil) { err = errors.New("array index out of bounds") } }() x = buf[i] }
Notice that more often than not, panicking is not the right solution. The Go paradigm is to check for errors explicitly. A program should only panic if the circumstances under which it panics do not happen during ordinary program executing. For instance, not being able to open a file is something that can happen and should not cause a panic while running out of memory is worth a panic. Nevertheless, this mechanism exists to be able to catch even these cases and perhaps shut down gracefully.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With