-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
The net.Error
interface defines Timeout
and Temporary
methods:
type Error interface {
error
Timeout() bool // Is the error a timeout?
Temporary() bool // Is the error temporary?
}
The meaning of "timeout" is reasonably intuitive: Was an error returned because an operation ran past a deadline?
However, the meaning of "temporary" is not obvious. What makes an error temporary vs. permanent? Is EHOSTUNREACH
temporary (because it may result from a temporary network routing error)? Is an operation that ran past a deadline permanent (because retrying the operation without extending the deadline will still fail)?
There is more discussion of net.Temporary
in here, and in the following thread:
#32463 (comment)
Looking at existing places where the standard library returns an error which implements a Temporary() bool
method returning true (not counting ones where the temporary status is propagated from a more-specific error):
Timeouts:
context
:context.DeadlineExceeded
crypto/tls
: AllDial
timeouts.net
: Various timeouts.net/http
: Timeout when reading headers or bodies. (The error type is namedhttpError
, but it is only used for timeouts.)net/http
: Also, HTTP/2 timeout reading response headers.os
:os.ErrDeadlineExceeded
(defined ininternal/poll
)
Non-timeouts:
net
:ECONNRESET
andECONNABORTED
errors returned byaccept()
.net
:EAI_AGAIN
errors returned bygetaddrinfo()
.syscall/syscall_plan9.go
,syscall/syscall_unix.go
,syscall/syscall_js.go
,syscall/syscall_windows.go
:
EINTR
,EMFILE
,ENFILE
, plus errors also considered timeouts:EAGAIN
,EWOULDBLOCK
,EBUSY
, andETIMEDOUT
. (Some minor variation between operating systems.)
Ignoring cases where "temporary" is redundant with "timeout", the only "temporary" errors I can find are ones resulting from a small number of syscall errors. In most cases, "temporary" appears to mean "a timeout, or out of file descriptors". The documentation for net.Error
does not make the limited scope of "temporary" errors obvious.
There are a number of other places in the standard library where errors propagate through the "temporary" status of another error. The existence of these Temporary()
methods makes it seem (to me at least) as if temporary errors are more prevalent than they actually are.
Perhaps there is a useful definition of a "temporary" error. Perhaps we should provide a well-defined os.ErrTemporary
or similar. That is not this proposal.
I believe that:
- We currently do not have a good definition of "temporary".
- Figuring out what errors implement
net.Error
and indicate a "temporary" status is difficult. - The cases where
Temporary
does not implyTimeout
are surprising and not particularly useful.
I propose that we deprecate the Temporary
method:
type Error interface {
error
Timeout() bool // Is the error a timeout?
// Deprecated: Temporary errors are not well-defined.
// Most temporary errors are timeouts, and the few exceptions are surprising.
// Do not use this method.
Temporary() bool
}