Golang errors: Difference between revisions

From wikinotes
Line 30: Line 30:
</blockquote><!-- Error Objects -->
</blockquote><!-- Error Objects -->


== Error Verification ==
== Error Types ==
<blockquote>
<blockquote>
Errors are often pre-defined as constants


<syntaxhighlight lang="go">
require "errors"
var UserNotExistError = errors.New("User does not exist")
func DoAs(user string) error {
    // ...
    return UserNotExistError
}
</syntaxhighlight>
</blockquote><!-- Error Verification -->
</blockquote><!-- Error Verification -->
</blockquote><!-- Errors -->
</blockquote><!-- Errors -->

Revision as of 13:04, 18 June 2022

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
}