How to convert panic to error in Golang?

Learn how to convert panic to error in Golang so that it can be handled more gracefully.

Go is one of my favourite programming languages and ever since I started using it, I just fell in love with it. I will write a detailed article on what I love about Go on some other day, but today we are here to solve the problem of converting panic to error in Golang.

I will tell a bit about how I stumbled on this problem and then we will look at the solution for it.

So, I was working on a Go project boilerplate for our company as we wanted to move all backend services to Go. This boilerplace had to come in with all the basic things in place like logger, ORM, security, standardized API response strictures and much more.

While working on a middleware for handling panic, I stumbled on this problem where the top most layer that handles the response expected an object of type error, while here I had a panic with me. So, converting panic to error would allow me to handle such scenarios more gracefully.

If you too are in a similar situation and looking for way to cast panic into error, then look at the code below.

Code With Panic

package main

import "fmt"

func main() {
    res := someFuncThatCanPanic(1)
	fmt.Println("Res", res)

	res = someFuncThatCanPanic(2)
	fmt.Println("Res", res)
}

func someFuncThatCanPanic(num int) string {
	if num%2 == 0 {
		panic("Save Me !!!!!")
	}

	return "Dinesh"
}

Solution - Code with Panic converted to Error

package main

import "fmt"

func main() {
	res, err := gracefulFunc(1)
	if err != nil {
		fmt.Println("Err", err)
	} else {
		fmt.Println("Res", res)
	}

	res, err = gracefulFunc(2)
	if err != nil {
		fmt.Println("Err", err)
	} else {
		fmt.Println("Res", res)
	}

}

func gracefulFunc(num int) (res string, panicErr error) {

	defer func() {
		if err := recover(); err != nil {
			panicErr = fmt.Errorf("%v", err)
		}
	}()

	res = someFuncThatCanPanic(num)

	return
}

func someFuncThatCanPanic(num int) string {
	if num%2 == 0 {
		panic("Save Me !!!!!")
	}

	return "Dinesh"
}

As you can see above that we introduced a function between main & someFuncThatCanPanic called gracefulFunc. The job of this function is to recover from the panic and always return an error object in case of any issue.

Do let us in the comments below if you faced any issue in the implementation above to convert panic to error in Golang.