Working with Errors in Go 1.13
17 Oct 2019
Tags: errors, technical

Damien Neil and Jonathan Amsterdam

* Introduction

Go’s treatment of [[https://blog.golang.org/errors-are-values][errors as values]]
has served us well over the last decade. Although the standard library’s support
for errors has been minimal—just the `errors.New` and `fmt.Errorf` functions,
which produce errors that contain only a message—the built-in `error` interface
allows Go programmers to add whatever information they desire. All it requires
is a type that implements an `Error` method:


    type QueryError struct {
        Query string
        Err   error
    }

    func (e *QueryError) Error() string { return e.Query + ": " + e.Err.Error() }

Error types like this one are ubiquitous, and the information they store varies
widely, from timestamps to filenames to server addresses. Often, that
information includes another, lower-level error to provide additional context.

The pattern of one error containing another is so pervasive in Go code that,
after [[https://golang.org/issue/29934][extensive discussion]], Go 1.13 added
explicit support for it. This post describes the additions to the standard
library that provide that support: three new functions in the `errors` package,
and a new formatting verb for `fmt.Errorf`.

Before describing the changes in detail, let's review how errors are examined
and constructed in previous versions of the language.

* Errors before Go 1.13

** Examining errors

Go errors are values. Programs make decisions based on those values in a few
ways. The most common is to compare an error to `nil` to see if an operation
failed.

    if err != nil {
        // something went wrong
    }

Sometimes we compare an error to a known _sentinel_ value, to see if a specific error has occurred.

    var ErrNotFound = errors.New("not found")

    if err == ErrNotFound {
        // something wasn't found
    }

An error value may be of any type which satisfies the language-defined `error`
interface. A program can use a type assertion or type switch to view an error
value as a more specific type.

    type NotFoundError struct {
        Name string
    }

    func (e *NotFoundError) Error() string { return e.Name + ": not found" }

    if e, ok := err.(*NotFoundError); ok {
        // e.Name wasn't found
    }


** Adding information

Frequently a function passes an error up the call stack while adding information
to it, like a brief description of what was happening when the error occurred. A
simple way to do this is to construct a new error that includes the text of the
previous one:

    if err != nil {
        return fmt.Errorf("decompress %v: %v", name, err)
    }

Creating a new error with `fmt.Errorf` discards everything from the original
error except the text. As we saw above with `QueryError`, we may sometimes want
to define a new error type that contains the underlying error, preserving it for
inspection by code. Here is `QueryError` again:


    type QueryError struct {
        Query string
        Err   error
    }

Programs can look inside a `*QueryError` value to make decisions based on the
underlying error. You'll sometimes see this referred to as "unwrapping" the
error.

    if e, ok := err.(*QueryError); ok && e.Err == ErrPermission {
        // query failed because of a permission problem
    }


The `os.PathError` type in the standard library is another example of one error which contains another.

* Errors in Go 1.13

** The Unwrap method

Go 1.13 introduces new features to the `errors` and `fmt` standard library
packages to simplify working with errors that contain other errors. The most
significant of these is a convention rather than a change: an error which
contains another may implement an `Unwrap` method returning the underlying
error. If `e1.Unwrap()` returns `e2`, then we say that `e1` _wraps_ `e2`, and
that you can _unwrap_ `e1` to get `e2`.

Following this convention, we can give the `QueryError` type above an `Unwrap`
method that returns its contained error:

    func (e *QueryError) Unwrap() error { return e.Err }

The result of unwrapping an error may itself have an `Unwrap` method; we call
the sequence of errors produced by repeated unwrapping the _error_chain_.

** Examining errors with Is and As

The Go 1.13 `errors` package includes two new functions for examining errors: `Is` and `As`. 

The `errors.Is` function compares an error to a value.

    // Similar to:
    //   if err == ErrNotFound { … }
    if errors.Is(err, ErrNotFound) {
        // something wasn't found
    }

The `As` function tests whether an error is a specific type.

    // Similar to:
    //   if e, ok := err.(*QueryError); ok { … }
    var e *QueryError
    if errors.As(err, &e) {
        // err is a *QueryError, and e is set to the error's value
    }

In the simplest case, the `errors.Is` function behaves like a comparison to a
sentinel error, and the `errors.As` function behaves like a type assertion. When
operating on wrapped errors, however, these functions consider all the errors in
a chain. Let's look again at the example from above of unwrapping a `QueryError`
to examine the underlying error:

    if e, ok := err.(*QueryError); ok && e.Err == ErrPermission {
        // query failed because of a permission problem
    }

Using the `errors.Is` function, we can write this as:

    if errors.Is(err, ErrPermission) {
        // err, or some error that it wraps, is a permission problem
    }


The `errors` package also includes a new `Unwrap` function which returns the
result of calling an error's `Unwrap` method, or `nil` when the error has no
`Unwrap` method. It is usually better to use `errors.Is` or `errors.As`,
however, since these functions will examine the entire chain in a single call.

** Wrapping errors with %w

As mentioned earlier, it is common to use the `fmt.Errorf` function to add additional information to an error.

    if err != nil {
        return fmt.Errorf("decompress %v: %v", name, err)
    }

In Go 1.13, the `fmt.Errorf` function supports a new `%w` verb. When this verb
is present, the error returned by `fmt.Errorf` will have an `Unwrap` method
returning the argument of `%w`, which must be an error. In all other ways, `%w`
is identical to `%v`.

    if err != nil {
        // Return an error which unwraps to err.
        return fmt.Errorf("decompress %v: %w", name, err)
    }

Wrapping an error with `%w` makes it available to `errors.Is` and `errors.As`:

    err := fmt.Errorf("access denied: %w”, ErrPermission)
    ...
    if errors.Is(err, ErrPermission) ...


** Whether to Wrap

When adding additional context to an error, either with `fmt.Errorf` or by
implementing a custom type, you need to decide whether the new error should wrap
the original. There is no single answer to this question; it depends on the
context in which the new error is created. Wrap an error to expose it to
callers. Do not wrap an error when doing so would expose implementation details.

As one example, imagine a `Parse` function which reads a complex data structure
from an `io.Reader`. If an error occurs, we wish to report the line and column
number at which it occurred. If the error occurs while reading from the
`io.Reader`, we will want to wrap that error to allow inspection of the
underlying problem. Since the caller provided the `io.Reader` to the function,
it makes sense to expose the error produced by it.

In contrast, a function which makes several calls to a database probably should
not return an error which unwraps to the result of one of those calls. If the
database used by the function is an implementation detail, then exposing these
errors is a violation of abstraction. For example, if the `LookupUser` function
of your package `pkg` uses Go's `database/sql` package, then it may encounter a
`sql.ErrNoRows` error. If you return that error with
`fmt.Errorf("accessing`DB:`%v",`err)`
then a caller cannot look inside to find the `sql.ErrNoRows`. But if
the function instead returns `fmt.Errorf("accessing`DB:`%w",`err)`, then a
caller could reasonably write

    err := pkg.LookupUser(...)
    if errors.Is(err, sql.ErrNoRows) …

At that point, the function must always return `sql.ErrNoRows` if you don't want
to break your clients, even if you switch to a different database package. In
other words, wrapping an error makes that error part of your API. If you don't
want to commit to supporting that error as part of your API in the future, you
shouldn't wrap the error.

It’s important to remember that whether you wrap or not, the error text will be
the same. A _person_ trying to understand the error will have the same information
either way; the choice to wrap is about whether to give _programs_ additional
information so they can make more informed decisions, or to withhold that
information to preserve an abstraction layer.

* Customizing error tests with Is and As methods

The `errors.Is` function examines each error in a chain for a match with a
target value. By default, an error matches the target if the two are equal. In
addition, an error in the chain may declare that it matches a target by
implementing an `Is` _method_.

As an example, consider this error inspired by the
[[https://commandcenter.blogspot.com/2017/12/error-handling-in-upspin.html][Upspin error package]]
which compares an error against a template, considering only fields which are
non-zero in the template:

    type Error struct {
        Path string
        User string
    }

    func (e *Error) Is(target error) bool {
        t, ok := target.(*Error)
        if !ok {
            return false
        }
        return (e.Path == t.Path || t.Path == "") &&
               (e.User == t.User || t.User == "")
    }

    if errors.Is(err, &Error{User: "someuser"}) {
        // err's User field is "someuser".
    }

The `errors.As` function similarly consults an `As` method when present.

* Errors and package APIs

A package which returns errors (and most do) should describe what properties of
those errors programmers may rely on. A well-designed package will also avoid
returning errors with properties that should not be relied upon.

The simplest specification is to say that operations either succeed or fail,
returning a nil or non-nil error value respectively. In many cases, no further
information is needed.

If we wish a function to return an identifiable error condition, such as "item
not found," we might return an error wrapping a sentinel.

    var ErrNotFound = errors.New("not found")

    // FetchItem returns the named item.
    //
    // If no item with the name exists, FetchItem returns an error
    // wrapping ErrNotFound.
    func FetchItem(name string) (*Item, error) {
        if itemNotFound(name) {
            return nil, fmt.Errorf("%q: %w", name, ErrNotFound)
        }
        // ...
    }

There are other existing patterns for providing errors which can be semantically
examined by the caller, such as directly returning a sentinel value, a specific
type, or a value which can be examined with a predicate function.

In all cases, care should be taken not to expose internal details to the user.
As we touched on in "Whether to Wrap" above, when you return
an error from another package you should convert the error to a form that does
not expose the underlying error, unless you are willing to commit to returning
that specific error in the future.

    f, err := os.Open(filename)
    if err != nil {
        // The *os.PathError returned by os.Open is an internal detail.
        // To avoid exposing it to the caller, repackage it as a new
        // error with the same text. We use the %v formatting verb, since
        // %w would permit the caller to unwrap the original *os.PathError.
        return fmt.Errorf("%v", err)
    }

If a function is defined as returning an error wrapping some sentinel or type,
do not return the underlying error directly.

    var ErrPermission = errors.New("permission denied")

    // DoSomething returns an error wrapping ErrPermission if the user
    // does not have permission to do something.
    func DoSomething() error {
        if !userHasPermission() {
            // If we return ErrPermission directly, callers might come
            // to depend on the exact error value, writing code like this:
            //
            //     if err := pkg.DoSomething(); err == pkg.ErrPermission { … }
            //
            // This will cause problems if we want to add additional
            // context to the error in the future. To avoid this, we
            // return an error wrapping the sentinel so that users must
            // always unwrap it:
            //
            //     if err := pkg.DoSomething(); errors.Is(err, pkg.ErrPermission) { ... }
            return fmt.Errorf("%w", ErrPermission)
        }
        // ...
    }

* Conclusion

Although the changes we’ve discussed amount to just three functions and a
formatting verb, we hope they will go a long way toward improving how errors are
handled in Go programs. We expect that wrapping to provide additional context
will become commonplace, helping programs to make better decisions and helping
programmers to find bugs more quickly.

As Russ Cox said in his [[https://blog.golang.org/experiment][GopherCon 2019 keynote]],
on the path to Go 2 we experiment, simplify and ship. Now that we’ve
shipped these changes, we look forward to the experiments that will follow.
