An (official) proposal for an exception-like mechanism in Google's Go
groups.google.com
groups.google.com
I'd like to see a mechanism where you could launch a goroutine such that it, and any goroutines it launches, all have a top level defer. That lets you launch potentially questionable third-party libraries in a goroutine safe in the knowledge that they will not take down your whole program.
Otherwise I like it.
Instead of "go foo()", you would "go dontPanic(foo)" or "go panicToChan(foo, errChan)".
I'm fairly certain this would work, and similar things are discussed in the replies to the linked post, but I haven't written much Go at all, so I can make no guarantees.
There can be a lot of them.
That's already possible so no change there. The child routine need only call panic or crash and it will destroy your program.
The fact that this does not make it possible to keep exceptions from being fatal is a limitation on how strongly exceptions are handled.
Maybe I'm missing something, but this does allow you to keep exceptions from being fatal using defer.
The problem comes in the fact that goroutines are considered cheap and are launched for all sorts of reasons. Sometimes in large numbers. If even one of those goroutines does not have a defer set up, then an exception can crash the program.
The use case I'm worried about is a webserver. In serving a web page I generally am happy to throw an exception, let it be caught at the top level, log it, then return a 500 page, internal server error. Watch your logs, fix the bugs, and release better software. However if you take this strategy with go, then the careless application programmer can accidentally take down the webserver.
What I'd like to be able to do is have a smart person set the webserver up, and then be able to let more junior programmers write code for an application on top of it knowing that there are some limits to the likely damage that they'll do.
This might help.
func GoCatch(f func ()) {
go func () {
defer func () {
e := recover()
if e != nil {
log.Stderr(e.String())
}
}()
f()
}
}