Golang errors

From wikinotes

Go seems to discourage the use of exception-style control-flows,
encouraging the use of errors in return-values instead.

Errors

Error Objects

Go prefers passing error objects as return values to exceptions.
Errors can be any object that expose the Error() string method.

require "errors"
require "fmt"

// build ad-hoc error
fmt.Errorf("User does not exist")
errors.New("User does not exist")

Functions generally return an error as the last value on fail,
or nil on success

func doThing (value int, error) {
    if success {
        return 123, nil                          // success
    }
    return 0, fmt.Errorf("User does not exist")  // fail
}

Error Types

Errors are often pre-defined as constants

require "errors"

var UserNotExistError = errors.New("User does not exist")

func DoAs(user string) error {
    return UserNotExistError
}

Panic

panic

A panic is go's repacement for exceptions.
If a panic is not caught, it bubbles to the top of the application, and it exits with an error.

panic("I encountered an error")

recover

You can check the value of a panic (if one has been raised) using recover().

panic("I encountered an error")  // raise a panic
err := recover()                 // returns nil/error-msg-if-present

It is common to handle panics in deferred functions

func main() {
    fmt.Println("hi")
    panic("I just encountered an error")
    defer func() {
        if err := recover(); err != nil {
            fmt.Println("Error: ", err)
            panic(err)                         // <<-- re-raise panic
        }
    }

    fmt.Println("bye")  // <-- never runs
}