Go: Panic Recover and Return Values

In working with external code I hit the following. The code provided a function for looking up a product’s price, returning the price if available and a possible error:

func Price(product string) (float64, error)

It was a simple function, and the error case was sensible, unknown product, out of stock, etc. However, I discovered that when the item was discontinued the function resulted in a panic from deep in the external code. While I’ll pursue reporting/fixing it, I needed to guard against it from my side immediately.

Go has a mechanism for dealing with panics, it’s the function recover(). Recover is, true to Go, simple, works, and does a little less than you’d ideally like. A simple use of recover might look like:

func divide(group int, n int) {    
defer func() {
if err := recover(); err != nil {
fmt.Println("Panic Divide by 0")
}
}()
// Cause an error when n = 0
fmt.Println(group/n)
}

In the above, without the use of recover divide() with n=0 would panic with a divide by zero error. By adding the deferred function with the recover, the panic will be caught and effectively suppressed.

Lets go back to the original issue, a panic in:

func Price(product string) (float64, error)

Can recover handle this panic scenario, maintaining the returned error value? Yes!

func SafePrice(product string) (price float64, err error) {
defer func() {
if p := recover(); p != nil {
err = p
}
}()
return Price(product)
}

With SafePrice() in place, here’s what happens. Under normal scenarios, you’ll get the price and error as returned by Price(), when there is a panic in Price(), the deferred function, will, on the way out, catch the panic with recover() and set the returned err of SafePrice() to the panic value. The panic is now an orderly and manageable returned error.

Graybeard code monkey, started on an Apple IIe, got a CS degree in the 80’s, and coded my way through C, C++, Objective-C, Java, Kotlin — and now Go.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store