user1663023
user1663023

Reputation:

Golang panic crash prevention

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?

Upvotes: 16

Views: 17026

Answers (3)

S.M.Mousavi
S.M.Mousavi

Reputation: 5226

I think panic is not same as exception. You can handle exception and running of routine will be continued. Whereas panic causes to termination current routine and you can not skip it.
Exception emits by OS generally and causes to run related routine. Instead panic emits by programmer manually and causes to exit goroutine.
You can define multiple exception for every piece of code within a function. Panic recovery mechanism works for whole function.
Exception designed to be handled whereas Panic designed to termination and panic recovering mechanism seems to be just a trick to control termination.

So exception handling is comparable with error handling.
But how you can take advantages of it in Golang?

I will describe my use case to answer your question.

There is two type of blocking error, Panic and Fatal. You can not recover from fatal error.
Sometimes you need to kill the process. But sometimes you need to restart it.
I used recover() mechanism to recovering from panic error in order to shutting down current goroutine and restarting main functionality.
So I must be careful about error type. Some situations need to emit fatal error such as missing necessary config file. And sometimes it is reasonable to restart the app. Think about all situations that you like to restart the app after crash. Such as:

  • overloaded service (which causes to DoS)
  • missing DBMS
  • unexpected error origin from other used go packages
  • crashing imagick process for example
  • and so on

So,
recover() is very beneficial in my case. It gives a chance to shutdown the process clearly before exiting.

Side Note: You can develop an bootstrapper app which will runs main app as detached process. It must re-run main app, if that process exited abnormally.
Use logging in order to debug while keeping your app run.

Upvotes: 1

Rob
Rob

Reputation: 1437

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.

Upvotes: 3

joshlf
joshlf

Reputation: 23557

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.

Upvotes: 12

Related Questions