Go: errors: As should allow target to be a nil pointer to a concrete type

Created on 18 Apr 2019  ·  7Comments  ·  Source: golang/go

What did you do?

example.com$ cat >./main.go <<EOF
package main

import (
        "errors"
        "fmt"
        "net"
)

func main() {
        const addr = "••••••••"
        conn, err := net.Dial("tcp", addr)
        if err != nil {
                if errors.As(err, (*net.InvalidAddrError)(nil)) {
                        fmt.Println("invalid address: %s")
                }
        }
        defer conn.Close()
}
EOF

example.com$ cat >./go.mod <<EOF
module example.com

go 1.12
EOF

example.com$ go version
go version devel +33fdc10a30 Wed Apr 17 13:37:58 2019 -0400 linux/amd64

example.com$ go run main.go

What did you expect to see?

errors.As being useful for type-checks even if I don't want to allocate space to store the result.

For this specific example:

invalid address: ••••••••

What did you see instead?

panic: errors: target must be a non-nil pointer

goroutine 1 [running]:
errors.As(0x54de60, 0xc000098000, 0x507020, 0x0, 0x0)
        /usr/local/google/home/bcmills/go/src/errors/wrap.go:86 +0x5eb
main.main()
        /tmp/tmp.8hp5hhWBDQ/example.com/main.go:13 +0xd5
exit status 2

This is the documented behavior of errors.As, but it seems strictly less useful than allowing a nil pointer of a concrete type.

FrozenDueToAge NeedsInvestigation

Most helpful comment

An error matches a type ... if it has a method As(interface{}) bool such that As(target) returns true.

So what should the As method of the error do if target is nil? Should all As method implementation check for nil pointers? Wouldn't this place a burden on all interface implementors?

--

An aside: the As function is currently documented:

An error matches a type if it is assignable to the target type,

Should that be "assignable through"? It only matches if the given error (or an unwrapped error) can be assigned to the "element" value of target. This seems like it needs some clarification.

All 7 comments

(See previously #30970, which relaxed a somewhat related constraint on err.)

CC @neild @jba @mpvl

I don't see a problem with this.

An error matches a type ... if it has a method As(interface{}) bool such that As(target) returns true.

So what should the As method of the error do if target is nil? Should all As method implementation check for nil pointers? Wouldn't this place a burden on all interface implementors?

--

An aside: the As function is currently documented:

An error matches a type if it is assignable to the target type,

Should that be "assignable through"? It only matches if the given error (or an unwrapped error) can be assigned to the "element" value of target. This seems like it needs some clarification.

Change https://golang.org/cl/179978 mentions this issue: errors: As target can be a typed nil pointer

Should all As method implementation check for nil pointers? Wouldn't this place a burden on all interface implementors?

That's true.

Should that be "assignable through"?

In the same CL linked above, I reworded that part of the doc. PTAL.

I think this API change is a mistake, for the reasons adg gives above.
It's a minor performance optimization that will cause problems in every As method implementation. It doens't balance out.

Abandoned the CL.

Was this page helpful?
0 / 5 - 0 ratings