Safe close connection in Golang

Qian Chen picture Qian Chen · Dec 10, 2013 · Viewed 10.8k times · Source

When I open a socket connection, I immediately put the socket.Close() logic in a defer function after the opening of the socket. However, what if the socket.Close() would cause another panic? Should I always nest another defer/recover inside the outer defer to prevent my program from crashing? Something like this: http://play.golang.org/p/GnEMQS-0jj

Thanks, Elgs

Answer

Caleb picture Caleb · Dec 11, 2013

Generally you don't need to worry much about panics. They usually represent two classes of errors: developer mistakes (nil references, array out of bounds) and system level errors you probably can't do much about (like running out of memory).

As others said socket.Close will not panic, rather it returns an error. If you do:

defer socket.Close()

The error is discarded and you don't need to do anything else.

But suppose you did want to recover from a panic. If you're recovery handler is deferred first then you don't need to do anything else:

func main() {
  defer func() {
    if err := recover(); err != nil {
      fmt.Println(err)
    }
  }()
  defer panic("this will be recovered")
}

Deferred functions are run in reverse order: http://golang.org/ref/spec#Defer_statements

Deferred functions are executed immediately before the surrounding function returns, in the reverse order they were deferred.