Skip to content

Commit

Permalink
net: support error.Is of network errors and context errors
Browse files Browse the repository at this point in the history
Change timeouts to be Is(context.DeadlineExceeded) and cancelation to
be Is(context.Canceled).

Fixes #51428

Change-Id: Ic580bd9da0f338e993fb79138875a78d99cc1a1d
Reviewed-on: https://go-review.googlesource.com/c/go/+/396877
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
  • Loading branch information
ianlancetaylor committed Apr 3, 2022
1 parent 73a81d8 commit 85b5f86
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
12 changes: 12 additions & 0 deletions doc/go1.19.html
Expand Up @@ -89,6 +89,18 @@ <h3 id="minor_library_changes">Minor changes to the library</h3>
Please report any such problems on <a href="/issue/new">the
issue tracker</a>.
</p>

<p><!-- CL 396877 -->
When a net package function or method returns an "I/O timeout"
error, the error will now satisfy <code>errors.Is(err,
context.Canceled)</code>. When a net package function returns
an "operation was canceled" error, the error will now satisfy
<code>errors.Is(err, context.DeadlineExceeded)</code>.
These changes are intended to make it easier for code to test
for cases in which a context cancelation or timeout causes a net
package function or method to return an error, while preserving
backward compatibility for error messages.
</p>
</dd>
</dl><!-- net -->

Expand Down
9 changes: 9 additions & 0 deletions src/net/error_test.go
Expand Up @@ -795,3 +795,12 @@ func parseLookupPortError(nestedErr error) error {
}
return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
}

func TestContextError(t *testing.T) {
if !errors.Is(errCanceled, context.Canceled) {
t.Error("errCanceled is not context.Canceled")
}
if !errors.Is(errTimeout, context.DeadlineExceeded) {
t.Error("errTimeout is not context.DeadlineExceeded")
}
}
23 changes: 17 additions & 6 deletions src/net/net.go
Expand Up @@ -413,15 +413,20 @@ var (
errMissingAddress = errors.New("missing address")

// For both read and write operations.
errCanceled = errors.New("operation was canceled")
errCanceled = canceledError{}
ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection")
)

// canceledError lets us return the same error string we have always
// returned, while still being Is context.Canceled.
type canceledError struct{}

func (canceledError) Error() string { return "operation was canceled" }

func (canceledError) Is(err error) bool { return err == context.Canceled }

// mapErr maps from the context errors to the historical internal net
// error values.
//
// TODO(bradfitz): get rid of this after adjusting tests and making
// context.DeadlineExceeded implement net.Error?
func mapErr(err error) error {
switch err {
case context.Canceled:
Expand Down Expand Up @@ -580,10 +585,12 @@ func (e InvalidAddrError) Temporary() bool { return false }
// errTimeout exists to return the historical "i/o timeout" string
// for context.DeadlineExceeded. See mapErr.
// It is also used when Dialer.Deadline is exceeded.
// error.Is(errTimeout, context.DeadlineExceeded) returns true.
//
// TODO(iant): We could consider changing this to os.ErrDeadlineExceeded
// in the future, but note that that would conflict with the TODO
// at mapErr that suggests changing it to context.DeadlineExceeded.
// in the future, if we make
// errors.Is(os.ErrDeadlineExceeded, context.DeadlineExceeded)
// return true.
var errTimeout error = &timeoutError{}

type timeoutError struct{}
Expand All @@ -592,6 +599,10 @@ func (e *timeoutError) Error() string { return "i/o timeout" }
func (e *timeoutError) Timeout() bool { return true }
func (e *timeoutError) Temporary() bool { return true }

func (e *timeoutError) Is(err error) bool {
return err == context.DeadlineExceeded
}

// DNSConfigError represents an error reading the machine's DNS configuration.
// (No longer used; kept for compatibility.)
type DNSConfigError struct {
Expand Down

0 comments on commit 85b5f86

Please sign in to comment.