Interpreting Go Socket Errors
March 17, 2011 Leave a comment
Go sockets returns error variables when something goes wrong, and the different error codes are documented here in the Go documentation. However I was not able to find coherent example that would show how the error variable is supposed to be used. Canonical way seems to be just checking it against nill and dump it out in case it’s something else, like this:
n, err := conn.Read(buffer[:]) if err != nill { fmt.Printf("%v\n", err) }
Real applications (especially system applications) need to branch based on error to recover properly, so just error description is not enough. I made here example what it’s possible to deduct from the error variable.
conn, err := net.Dial("tcp", "", "example.com:80") n, err := conn.Read(buffer[:]) if err != nil { // print error string e.g. // "read tcp example.com:80: resource temporarily unavailable" fmt.Printf("reader %v\n", err) // print type of the error, e.g. "*net.OpError" fmt.Printf("%T", err) if err == os.EINVAL { // socket is not valid or already closed fmt.Println("EINVAL"); } if err == os.EOF { // remote peer closed socket fmt.Println("EOF"); } // matching rest of the codes needs typecasting, errno is // wrapped on OpError if e, ok := err.(*net.OpError); ok { // print wrapped error string e.g. // "os.Errno : resource temporarily unavailable" fmt.Printf("%T : %v\n", e.Error, e.Error) if e.Timeout() { // is this timeout error? fmt.Println("TIMEOUT") } if e.Temporary() { // is this temporary error? True on timeout, // socket interrupts or when buffer is full fmt.Println("TEMPORARY") } // specific granular error codes in case we're interested switch e.Error { case os.EAGAIN: // timeout fmt.Println("EAGAIN") case os.EPIPE: // broken pipe (e.g. on connection reset) fmt.Println("EPIPE") default: // just write raw errno code, can be platform specific // (see syscall for definitions) fmt.Printf("%d\n", int64(e.Error.(os.Errno))) } }
For example in case read times out, the code would print following
read tcp 192.0.32.10:80: resource temporarily unavailable *net.OpError os.Errno : resource temporarily unavailable TIMEOUT TEMPORARY EAGAIN