Question: 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: 
Ask yourself these questions:

* Do you expect the exceptional situation to occur, regardless how well would you code your app? Do you think it should be useful to make the user aware of such condition as part of the normal usage of your app? Handle it as an error, because it concerns the application as working normally.
* Should that exceptional situation NOT occur if you code appropriately (and somewhat defensively)? (example: dividing by zero, or accessing an array element out of bounds) Is your app totally clueless under that error? Panic.
* Do you have your API and want to ensure users use it appropriately? Panic. Your API will seldom recover if used incorrectly.
A panic typically means something went unexpectedly wrong. Mostly used to fail fast on errors that shouldn’t occur during normal operation, or that we aren’t prepared to handle gracefully. So in this case just return the error, you don't want your program to panic.