5

In Golang, is it ok to run the function

err, value := function()
if err == nil {
  return value
}

instead of doing this:

err, value := function()
if err != nil {
  panic(err)
}
return err

If so, is there any time advantages / bonuses?

This is not a non-fatal error. I am trying to convert something to different types, and i'm not sure which I should use.

3
  • I've thought about that. The problem as I see it is that in the first example above you circumvent logging/handle errors. But if you're just planning on panicking and exiting the program at that point then maybe it doesn't matter all that much. Commented Apr 20, 2016 at 19:05
  • It really depends on the nature of the error. Go encourages prompt error handling unlike say Java where people frequently nest try/catches and let exceptions bubble up the call stack quite a bit before handling them. That being said, if it is a fatal error (like the program will not be able to recover) then you should probably panic. If it's an error you can anticipate and mitigate then you shouldn't panic. Using panic/recover as a sort of catch all for unanticipated errors is fairly common and I would reserve the use of panic for those types of circumstances. Commented Apr 20, 2016 at 19:13
  • Updated answer with your use case Commented Apr 20, 2016 at 19:27

1 Answer 1

6

A panic is similar to an exception, but doesn't get passed to the caller (aka when you call panic, it happens then and there; you don't get to wait). You should go with the first sample of your code, where you can attempt an action, fail, and continue.

func main() {
    s1 := rand.NewSource(time.Now().UnixNano())
    r1 := rand.New(s1)

    // Generate some random numbers, and call into add()
    for i := 0; i < 10; i++ {
        s, err := add(r1.Intn(100), r1.Intn(100))
        if err != nil {
            fmt.Println(err)
            continue
        }
        fmt.Println(s)
    }
}

// Error if we get a sum over 100
func add(a int, b int) (int, error) {
    s := a + b
    if s > 100 {
        return s, errors.New("Hey doofus, error!")
    }
    return s, nil
}

If you were to panic in this example, you'd be done (try it-- instead of returning an error do panic("Some error"). But instead, we determine there's an error, and we can try to generate another random number.

Like others have said, if you have a use case where you just can't recover (say you were trying to read from a file, but the file isn't there), you might decide it's better to panic. But if you have a long running process (like an API), you'll want to keep churning, despite any errors.

GoPlay here: http://play.golang.org/p/ThXTxVfM6R

OP has update his post with a use case-- he's trying to convert to a type. If you were to panic in this function, you would be dead in the water. Instead, we want to return an error, and let the caller decide what to do with the error. Take this as an example:

func interfaceToString(i interface{}) (string, error) {
    if i == nil {
        return "", errors.New("nil interface")
    }

    switch i.(type) {
    case string:
        return i.(string), nil
    case float64:
        return strconv.Itoa(int(i.(float64))), nil
    case int:
        return strconv.Itoa(i.(int)), nil
    }

    return "", errors.New(fmt.Sprintf("Unable to convert %v", i))
}

GoPlay here: http://play.golang.org/p/7y7v151EH4

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.