Should I use panic or return error?

laike9m picture laike9m · Jun 12, 2017 · Viewed 14.9k times · Source

Go provides two ways of handling errors, but I'm not sure which one to use.

Assuming I'm implementing a classic ForEach function which accepts a slice or a map as an argument. To check whether an iterable is passed in, I could do:

func ForEach(iterable interface{}, f interface{}) {
    if isNotIterable(iterable) {
        panic("Should pass in a slice or map!")
    }
}

or

func ForEach(iterable interface{}, f interface{}) error {
    if isNotIterable(iterable) {
        return fmt.Errorf("Should pass in a slice or map!")
    }
}

I saw some discussions saying panic() should be avoided, but people also say that if program cannot recover from error, you should panic().

Which one should I use? And what's the main principle for picking the right one?

Answer

Adrian picture Adrian · Jun 12, 2017

You should assume that a panic will be immediately fatal, for the entire program, or at the very least for the current goroutine. Ask yourself "when this happens, should the application immediately crash?" If yes, use a panic; otherwise, use an error.