I have the following code:
server := &http.Server{Addr: addr, Handler: r}
l, err := net.Listen("tcp", addr)
if err != nil {
logging.Error("Failed opening socket: %s", err)
}
if err := server.Serve(l); err != nil {
// error handling
}
When l.Close()
is called, server.Serve(l)
will exit with an error. I would like to know whether this is truly an error or just the result of someone calling l.Close()
(which is non error for me).
Is there a proper way to do this?
Some hack-ish way about TCP socket:
read_len, err := conn.Read(request)
if err != nil {
if err.Error() == "use of closed network connection" {
// Do something when socket closed
break
}
Try if err.Error() == "use of closed network connection"
under if err := server.Serve(l); err != nil {
, or in your TCP handler function.
With interfaces that implement io.ReadWriteCloser
you typically get back an io.EOF
and io.ErrUnexpectedEOF
error. net.Listener
implements io.Closer
, so I would expect it to also return this error, but it unfortunately does not follow this convention. Instead, it returns a privately declared errClosing in net.go.
Errors returned by net.Listener
are wrapped in net.OpError
. This struct has some additional information that may be helpful - specifically "Op" and "Err". "Op" tells you where the error occurred. When you execute Close() error
you get "accept" back. The documentation says you can also get "read" and "write" back.
To get net.OpError
, you can do this:
err := server.Serve(l)
if opErr, ok := err.(*net.OpError); ok {
// opErr.Op, opErr.Err, ...
}
Or like this (assuming that net.Listener
always returns a net.OpError
):
err := server.Serve(l).(*net.OpError)
net.OptError.Err returns the original error, which would be helpful if the error was exported. Either way I don't recommend checking the string as that could break in future versions. It's better to compare the error directly to the exported error, which you don't have.
net.OptError
also has a Temporary() bool
function declared. The net/http
package uses this to re-establish the connection on a increasing interval. So in the case of net/http
I would assume that any error that returns would be a result of calling Close() error
. Otherwise Temporary() bool
would return true, which net/http
catches for you.