A Nice Go Pattern: defer/panic

Typically in automation programs, I like to fail fast and log something useful whenever I run into some exceptional situation. A classic example is populating or updating a database with some external data source. If there is any issue with the file, it is easier to just exit immediately than corrupt the database.

In many situations though, there are resources allocated or initialized that I want to reset or unwind. So there is a need for some type of cleanup or finalization function. In languages that don't support concurrency, this is straightforward: just use a regular function and end it with some hard termination. But with Go, we have the added complexity of many goroutines possibly running in other contexts.

panic is the Go function dedicated to forcing termination while still retaining flow control. Many Go programmers only see panic output when we've done something really wrong or want to create a stack trace. But once you understand that panic works along with recover, you can also use it to terminate with your own flow control. I recently faced down the problem of deleting Consul keys that would have represented some facts about program completion; on failure, I wanted to remove them completely.

A nice way to achieve this is to create a finalization function that will be run with defer, which will attempt to recover any states from panic. Under normal conditions our program should not call panic so this function will simply exit, but in cases where we have called panic, we can capture the type of the panic state and do something useful.

Here is an example on the Playground

last update 2016-09-11