There's a code:
func (c *Connector) SendPacketFuture(p []byte) (future chan []byte) {
defer func() {
// TODO Check r to catch only chan panics
if r := recover(); r != nil {
future = nil
}
}()
t := newConnectorTask(p)
c.tasks <- t
future = t.PacketFromServerChan
return
}
TODO
is pretty self-explanatory.
c.tasks
is a channel and it can be closed by another goroutine. Since there's no safe way to send to channel that can be closed, I'm catching panics here. The problem is that different panics can occur and I want to react to the one that is raised by writing to a closed chan.
Is it possible to do this in Go?
The recover message in this case is an unexported error value from the runtime, with the string value of "send on closed channel"
.
The only thing you can do here is to match the error string:
if e, ok := r.(error); ok && w.Error() == "send on closed channel" {
fmt.Println("recover from send on closed channel")
}
https://play.golang.org/p/LNcfdE9Bg2
In actuality, what you probably need is a separate channel to signal when to exit.
t := newConnectorTask(p)
select {
case <-c.close:
// closing the c.close channel will unblock this case
return
case c.tasks <- t:
}