Better error handling

This commit is contained in:
Tevin Zhang 2016-06-01 17:47:04 +08:00
parent 944163aafd
commit 67b523fe25
3 changed files with 20 additions and 6 deletions

11
err.go
View File

@ -2,6 +2,7 @@ package tcp
import (
"errors"
"syscall"
)
// ErrTimeout indicates I/O timeout
@ -15,3 +16,13 @@ type timeoutError struct{}
func (e *timeoutError) Error() string { return "I/O timeout" }
func (e *timeoutError) Timeout() bool { return true }
func (e *timeoutError) Temporary() bool { return true }
// ErrConnect is an error occurs while connecting to the host
// To get the detail of underlying error, lookup ErrorCode() in 'man 2 connect'
type ErrConnect struct {
syscall.Errno
}
func newErrConnect(errCode int) *ErrConnect {
return &ErrConnect{syscall.Errno(errCode)}
}

View File

@ -31,7 +31,6 @@
package tcp
import (
"fmt"
"os"
"runtime"
"sync"
@ -97,12 +96,12 @@ func (s *Shaker) Test(addr string, timeout time.Duration) error {
// check for connect error
for {
succeed, err := s.wait(fd, timeoutMS)
if err != nil {
return fmt.Errorf("connect error: %s", err)
}
if reached(deadline) {
return ErrTimeout
}
if err != nil {
return err
}
if succeed {
return nil
}
@ -170,7 +169,7 @@ func (s *Shaker) wait(fd int, timeoutMS int) (bool, error) {
return false, os.NewSyscallError("getsockopt", err)
}
if errCode != 0 {
return false, fmt.Errorf("getsockopt[%d]", errCode)
return false, newErrConnect(errCode)
}
return true, nil
}

View File

@ -20,6 +20,10 @@ func ExampleShaker() {
case nil:
fmt.Println("Connect to Google succeded")
default:
fmt.Println("Connect to Google failed:", err)
if e, ok := err.(*ErrConnect); ok {
fmt.Println("Connect to Google failed:", e)
} else {
fmt.Println("Error occurred while connecting:", err)
}
}
}