Skip to content

errors: add example around unwrapping errors.Join #69586

@tpaschalis

Description

@tpaschalis

Go version

go version go1.21.6 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/tpaschalis/.cache/go-build'
GOENV='/home/tpaschalis/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/tpaschalis/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/tpaschalis/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.21.6'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/tpaschalis/Workspace/lox-go/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3067468203=/tmp/go-build -gno-record-gcc-switches'

What did you do?

I used errors.Join to group a bunch of errors together, but then realized that getting the individual entries back is not straightforward (unless I'm missing something); the ways I could spot to get the errors back would be to use errors.As or an inline cast to Unwrap() []error.

Should we include an example that shows people to handle this task to set some best practices/precedence?

https://go.dev/play/p/G5vw-xdqBvm

What did you see happen?

The errors package documentation states:

An error e wraps another error if e's type has one of the methods:
Unwrap() error
Unwrap() []error

If e.Unwrap() returns a non-nil error w or a slice containing w, then we say that e wraps w.
**A nil error returned from e.Unwrap() indicates that e does not wrap any error. **

It also states that

Join returns an error that wraps the given errors. Any nil error values are discarded.
[...]
A non-nil error returned by Join implements the Unwrap() []error method.

and that

Unwrap only calls a method of the form "Unwrap() error". In particular Unwrap does not unwrap errors returned by Join

I think that the two following statements are contradictory since calling errors.Unwrap(errors.Join(err1, err2)) will return nil, even though we said that Join returns a wrapped error. The first statement is only true for a kind of wrapped errors.

A nil error returned from e.Unwrap() indicates that e does not wrap any error
Join returns an error that wraps the given errors

What did you expect to see?

An documented way to get the individual errors back instead of fiddling to find the right interface to cast to.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions