]> Cypherpunks repositories - gostls13.git/commitdiff
all: remove os.ErrTemporary
authorDamien Neil <dneil@google.com>
Wed, 31 Jul 2019 20:13:39 +0000 (13:13 -0700)
committerDamien Neil <dneil@google.com>
Thu, 1 Aug 2019 15:39:45 +0000 (15:39 +0000)
As discussed in
https://github.com/golang/go/issues/32463#issuecomment-506833421
the classification of deadline-based timeouts as "temporary" errors is a
historical accident. I/O timeouts used to be duration-based, so they
really were temporary--retrying a timed-out operation could succeed. Now
that they're deadline-based, timeouts aren't temporary unless you reset
the deadline.

Drop ErrTemporary from Go 1.13, since its definition is wrong. We'll
consider putting it back in Go 1.14 with a clear definition and
deprecate net.OpError.Temporary.

Fixes #32463

Change-Id: I70cda664590d8872541e17409a5780da76920891
Reviewed-on: https://go-review.googlesource.com/c/go/+/188398
Reviewed-by: Jonathan Amsterdam <jba@google.com>
16 files changed:
api/go1.13.txt
src/context/context.go
src/internal/oserror/errors.go
src/internal/oserror/errors_test.go
src/internal/poll/fd.go
src/net/cgo_unix.go
src/net/http/transport.go
src/net/net.go
src/net/pipe.go
src/net/url/url.go
src/os/error.go
src/syscall/syscall_js.go
src/syscall/syscall_nacl.go
src/syscall/syscall_plan9.go
src/syscall/syscall_unix.go
src/syscall/syscall_windows.go

index 16f11cf2b78329042e33b6250624dee8a45a9566..a8e39ce8ea8a5e7a6bcd3eb0943bf61abd4e851e 100644 (file)
@@ -237,7 +237,6 @@ pkg os (netbsd-arm64), const O_SYNC = 128
 pkg os (netbsd-arm64), const O_TRUNC = 1024
 pkg os (netbsd-arm64), const PathListSeparator = 58
 pkg os (netbsd-arm64), const PathSeparator = 47
-pkg os, var ErrTemporary error
 pkg os, var ErrTimeout error
 pkg path/filepath (netbsd-arm64-cgo), const ListSeparator = 58
 pkg path/filepath (netbsd-arm64-cgo), const Separator = 47
index 05d01d0294adaf9c99d0cd520e621427213821e4..b400396513ef2d8cc6358dc9ef44fc00e703a8bf 100644 (file)
@@ -164,7 +164,7 @@ func (deadlineExceededError) Error() string   { return "context deadline exceede
 func (deadlineExceededError) Timeout() bool   { return true }
 func (deadlineExceededError) Temporary() bool { return true }
 func (deadlineExceededError) Is(target error) bool {
-       return target == oserror.ErrTimeout || target == oserror.ErrTemporary
+       return target == oserror.ErrTimeout
 }
 
 // An emptyCtx is never canceled, has no values, and has no deadline. It is not
index 8bd17c8b562ff98a03ff6665af5ca0de78f69193..8fccc9548208cc477d8a906038fe64580829ed8a 100644 (file)
@@ -15,7 +15,6 @@ var (
        ErrExist      = errors.New("file already exists")
        ErrNotExist   = errors.New("file does not exist")
        ErrClosed     = errors.New("file already closed")
-       ErrTemporary  = temporaryError{}
        ErrTimeout    = timeoutError{}
 )
 
@@ -45,20 +44,3 @@ func IsTimeout(err error) bool {
        }
        return false
 }
-
-// IsTemporary reports whether err indicates a temporary condition.
-func IsTemporary(err error) bool {
-       for err != nil {
-               if err == ErrTemporary {
-                       return true
-               }
-               if x, ok := err.(interface{ Temporary() bool }); ok {
-                       return x.Temporary()
-               }
-               if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(ErrTemporary) {
-                       return true
-               }
-               err = errors.Unwrap(err)
-       }
-       return false
-}
index 6d6a56a0c74719f63fe4ce192db9c9942bb63b17..bf3e057ccf70258b5c66b49f6d287b4ff99331a8 100644 (file)
@@ -9,15 +9,13 @@ import (
 )
 
 type ttError struct {
-       timeout   bool
-       temporary bool
+       timeout bool
 }
 
 func (e ttError) Error() string {
-       return fmt.Sprintf("ttError{timeout:%v temporary:%v}", e.timeout, e.temporary)
+       return fmt.Sprintf("ttError{timeout:%v}", e.timeout)
 }
-func (e ttError) Timeout() bool   { return e.timeout }
-func (e ttError) Temporary() bool { return e.temporary }
+func (e ttError) Timeout() bool { return e.timeout }
 
 type isError struct {
        err error
@@ -43,21 +41,3 @@ func TestIsTimeout(t *testing.T) {
                }
        }
 }
-
-func TestIsTemporary(t *testing.T) {
-       for _, test := range []struct {
-               want bool
-               err  error
-       }{
-               {true, ttError{temporary: true}},
-               {true, isError{os.ErrTemporary}},
-               {true, os.ErrTemporary},
-               {true, fmt.Errorf("wrap: %w", os.ErrTemporary)},
-               {false, ttError{temporary: false}},
-               {false, errors.New("error")},
-       } {
-               if got, want := oserror.IsTemporary(test.err), test.want; got != want {
-                       t.Errorf("IsTemporary(err) = %v, want %v\n%+v", got, want, test.err)
-               }
-       }
-}
index 784bea4b5a260924402cebcd2a872c684b419ade..5009e2671b023ecf2e6fe2a8256723cb0d498111 100644 (file)
@@ -48,7 +48,7 @@ func (e *TimeoutError) Timeout() bool   { return true }
 func (e *TimeoutError) Temporary() bool { return true }
 
 func (e *TimeoutError) Is(target error) bool {
-       return target == oserror.ErrTimeout || target == oserror.ErrTemporary
+       return target == oserror.ErrTimeout
 }
 
 // ErrNotPollable is returned when the file or socket is not suitable
index b9a6ffaa60efc927b880131125df408bcbc8e6ea..c31cbfd814a3eb177b9a1f06e33a45c5bf88f1ec 100644 (file)
@@ -40,8 +40,6 @@ func (eai addrinfoErrno) Timeout() bool   { return false }
 
 func (eai addrinfoErrno) Is(target error) bool {
        switch target {
-       case os.ErrTemporary:
-               return eai.Temporary()
        case os.ErrTimeout:
                return eai.Timeout()
        }
index 2f9bdc2700dea201eb2693ea29832132a216d7c0..e3a1a10cc61f2aa05c4a09d62cc2544f353f88ee 100644 (file)
@@ -2288,8 +2288,6 @@ func (e *httpError) Is(target error) bool {
        switch target {
        case os.ErrTimeout:
                return e.timeout
-       case os.ErrTemporary:
-               return true
        }
        return false
 }
@@ -2629,7 +2627,7 @@ func (tlsHandshakeTimeoutError) Temporary() bool { return true }
 func (tlsHandshakeTimeoutError) Error() string   { return "net/http: TLS handshake timeout" }
 
 func (tlsHandshakeTimeoutError) Is(target error) bool {
-       return target == os.ErrTimeout || target == os.ErrTemporary
+       return target == os.ErrTimeout
 }
 
 // fakeLocker is a sync.Locker which does nothing. It's used to guard
index b3f9b8ba07f04bd3c098af33a1ae70047c967d8b..54e1ac383ae3e666128dc080905012c39b728010 100644 (file)
@@ -518,8 +518,6 @@ func (e *OpError) Temporary() bool {
 
 func (e *OpError) Is(target error) bool {
        switch target {
-       case os.ErrTemporary:
-               return e.Temporary()
        case os.ErrTimeout:
                return e.Timeout()
        }
@@ -619,8 +617,6 @@ func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }
 
 func (e *DNSError) Is(target error) bool {
        switch target {
-       case os.ErrTemporary:
-               return e.Temporary()
        case os.ErrTimeout:
                return e.Timeout()
        }
index 8cc127464b1e8ef7cdd31b3b5a3df1a21d9b0e95..5abc4aabe6d4a8de852676434484bb6448498936 100644 (file)
@@ -86,7 +86,7 @@ func (timeoutError) Timeout() bool   { return true }
 func (timeoutError) Temporary() bool { return true }
 
 func (timeoutError) Is(target error) bool {
-       return target == os.ErrTemporary || target == os.ErrTimeout
+       return target == os.ErrTimeout
 }
 
 type pipeAddr struct{}
index 7f6ff93ce4657a18a7ac6cf8332f80c458809c6c..3212b9e998d8040187b0c8276d8fa08b942da08c 100644 (file)
@@ -26,10 +26,16 @@ type Error struct {
        Err error
 }
 
-func (e *Error) Unwrap() error   { return e.Err }
-func (e *Error) Error() string   { return e.Op + " " + e.URL + ": " + e.Err.Error() }
-func (e *Error) Timeout() bool   { return oserror.IsTimeout(e.Err) }
-func (e *Error) Temporary() bool { return oserror.IsTemporary(e.Err) }
+func (e *Error) Unwrap() error { return e.Err }
+func (e *Error) Error() string { return e.Op + " " + e.URL + ": " + e.Err.Error() }
+func (e *Error) Timeout() bool { return oserror.IsTimeout(e.Err) }
+
+func (e *Error) Temporary() bool {
+       t, ok := e.Err.(interface {
+               Temporary() bool
+       })
+       return ok && t.Temporary()
+}
 
 func ishex(c byte) bool {
        switch {
index 0c2e6a73220a729dd10da1b17efe3b70281f64b0..4cf35f2b773f237daa4b4e64564f0b41ef9c7ebc 100644 (file)
@@ -23,7 +23,6 @@ var (
        ErrNotExist   = errNotExist()   // "file does not exist"
        ErrClosed     = errClosed()     // "file already closed"
        ErrTimeout    = errTimeout()    // "deadline exceeded"
-       ErrTemporary  = errTemporary()  // "temporary error"
        ErrNoDeadline = errNoDeadline() // "file type does not support deadline"
 )
 
@@ -33,7 +32,6 @@ func errExist() error      { return oserror.ErrExist }
 func errNotExist() error   { return oserror.ErrNotExist }
 func errClosed() error     { return oserror.ErrClosed }
 func errTimeout() error    { return oserror.ErrTimeout }
-func errTemporary() error  { return oserror.ErrTemporary }
 func errNoDeadline() error { return poll.ErrNoDeadline }
 
 type timeout interface {
index 99f9a935fe5ff9b1d782d956daad5b9ac0af19a5..6db01c32f1108a97ea69adde7cabfe25079c03b0 100644 (file)
@@ -58,8 +58,6 @@ func (e Errno) Error() string {
 
 func (e Errno) Is(target error) bool {
        switch target {
-       case oserror.ErrTemporary:
-               return e.Temporary()
        case oserror.ErrTimeout:
                return e.Timeout()
        case oserror.ErrPermission:
index 3fc504fd9f2c4d3946c0d639f2eb5d09fe565bb7..33ad8bfab040a0c07da5f92d15abb4b806d2fdce 100644 (file)
@@ -65,8 +65,6 @@ func (e Errno) Error() string {
 
 func (e Errno) Is(target error) bool {
        switch target {
-       case oserror.ErrTemporary:
-               return e.Temporary()
        case oserror.ErrTimeout:
                return e.Timeout()
        case oserror.ErrPermission:
index 9b5a2940b07aeb1a855f0a8ddd02dbc275e6e0ab..d1b4bd9bd51a97566e7192a58f5af35fef58ec29 100644 (file)
@@ -29,8 +29,6 @@ func NewError(s string) error { return ErrorString(s) }
 
 func (e ErrorString) Is(target error) bool {
        switch target {
-       case oserror.ErrTemporary:
-               return e.Temporary()
        case oserror.ErrTimeout:
                return e.Timeout()
        case oserror.ErrPermission:
index 1b66e3bb1190706874897f556d5be8ca23d1e853..4bb7799d53d4bad18ef071d093f928b57c2a613c 100644 (file)
@@ -121,8 +121,6 @@ func (e Errno) Error() string {
 
 func (e Errno) Is(target error) bool {
        switch target {
-       case oserror.ErrTemporary:
-               return e.Temporary()
        case oserror.ErrTimeout:
                return e.Timeout()
        case oserror.ErrPermission:
index 6201b6475d71eea90af8cd62a7d42dae08880efa..aa4cfa724336d8065f57b1baf1f4d02e35dcb2c1 100644 (file)
@@ -115,8 +115,6 @@ const _ERROR_BAD_NETPATH = Errno(53)
 
 func (e Errno) Is(target error) bool {
        switch target {
-       case oserror.ErrTemporary:
-               return e.Temporary()
        case oserror.ErrTimeout:
                return e.Timeout()
        case oserror.ErrPermission: