Issue
I am using the conn.SetReadDeadline
method to set the read timeout for conn
, When conn.Read
waits for more than the specified time, it will return and return an error of type *net.OpError
. This error is returned by the net
package after wrapping all non-io.EOF
errors.
I can get the error before wrapping with Unwrap()
. A timeout error is an error of type *poll.DeadlineExceededError
. I use statements like this in my code to handle timeout errors precisely.
import "internal/poll"
_, err = conn.Read(p)
if err != nil {
if pe, ok := err.(*net.OpError); ok {
err = pe.Unwrap()
if timeout, ok := err.(*poll.DeadlineExceededError); ok {
log.Error(fmt.Sprintf("%T, %s", timeout, timeout))
}
}
return
}
I received an use of internal package internal/poll not allowed
error while running the program. The compiler tells me that internal packages cannot be used.
I googled and found a solution to delete the internal
folder, is this the final solution? Will there be a better solution?
Solution
The os
package exports that error as os.ErrDeadlineExceeded
. You can try :
if errors.Is(err, os.ErrDeadlineExceeded) {
log.Error("Timeout error")
}
Another indication that an error is a "timeout" error is if it has a Timeout() bool
method, which returns true
when called.
This is part of the net.Error
interface (although this interface has an extra method, which is documented as deprecated), and implemented by the net.OpError
type (and also by the internal poll.DeadlineExceededError
type).
There are several functions (net.OpError.IsTimeout()
, os.SyscallError.IsTimeout()
and the public function os.IsTimeout()
for example) that implement a timeout checking by directly casting the error value to a timeout
interface.
If you want to deal with errors that can be wrapped one into another, you may want to implement your own isTimeout()
check using errors.As(...)
:
// isTimeout : use errors.As() to unwrap errors and check if a sub error is a Timeout error
func isTimeout(err error) bool {
var terr interface{ Timeout() bool }
return errors.As(err, &terr) && terr.Timeout()
}
https://go.dev/play/p/OhhKY3XsGjZ
Answered By – LeGEC
Answer Checked By – Senaida (GoLangFix Volunteer)