10 comments

[ 6.4 ms ] story [ 31.7 ms ] thread
From this one ill-behaved goroutine could take down your program.

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.

I think you could easily write a function that defers a handler that will swallow any errors or send them on a channel and calls the supplied function.

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.

You have to do that for every goroutine that is launched.

There can be a lot of them.

> From this one ill-behaved goroutine could take down your program.

That's already possible so no change there. The child routine need only call panic or crash and it will destroy your program.

Right. There is currently no exception handling and so exceptions are fatal. The point of exception handling is to make it possible to make exceptions not be fatal.

The fact that this does not make it possible to keep exceptions from being fatal is a limitation on how strongly exceptions are handled.

> 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.

When an exception is thrown in a goroutine you climb the stack and any defer can trap the exception. However if you climb the stack of a goroutine to the top and there is no defer, you'll exit with a stack backtrace. So every goroutine has to have a defer if you want protection.

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.

> If even one of those goroutines does not have a defer set up, then an exception can crash the program.

This might help.

    func GoCatch(f func ()) {
      go func () {
        defer func () {
          e := recover()
          if e != nil {
            log.Stderr(e.String())
          }
        }()
        f()
      }
    }
Yes, but my concern was, and remains, what happens with third party libraries. The fact that I can rewrite my stuff easily does not mean that I can rewrite that stuff as easily.
I guess I'm not really understanding the problem. What third-party library weakness do you think Go is especially susceptible to, exactly? An example would be nice.