Golang panic crash prevention

2019-02-21 18:19发布

问题:

In Golang a panic without a recover will crash the process, so I end up putting the following code snippet at the beginning of every function:

defer func() {
    if err := recover(); err != nil {
        fmt.Println(err)
    }
}()

just in order to prevent my program from crashing. Now I'm wondering, is it really the way to go? Because I think it looks a little bit strange to put the same code everywhere.

It seems to me, the Java way, bubbling the exceptions up to the calling function, until the main function is a better way to control the exceptions/panics. I understand it's by Go's design, but what is the advantage of immediately crashing the process just like what Go does?

回答1:

You should only recover from a panic if you know exactly why. A Go program will panic under essentially two circumstances:

  • A program logic error (such as a nil pointer dereference or out-of-bounds array or slice access)
  • An intentional panic (called using panic(...)) from either your code or code that your code calls

In the first case, a crash is appropriate because it means that your program has entered a bad state and shouldn't keep executing. In the second case, you should only recover from the panic if you expect it. The best way to explain this is simply to say that it's extremely rare, and you'll know that case if you see it. I'm almost positive that whatever code you're writing, you don't need to recover from panics.



回答2:

Generally, even with exceptions, you catch them at a "FaultBarrier". It's usually the place where all new threads are spawned. The point is to catch and log unexpected failures.

In Go, you use return values for all expected failures. The framework in which you work will generally have a fault barrier to catch a session (ie: usually an http transaction) and log the problem. The only other place I see recover happening is things like non-idempotent Close function. If you have a situation where you can't tell if something is already closed but know it must be closed, then you could end up doing a recover so that a second close panic will be ignored, rather than failing what you are doing all the way up to the FaultBarrier.