Having spent the last few weeks trying to become literate in Golang, I can
confidently say that all of my favorite tricks in the language involved the
defer statement. Here’s one
that I gleaned from the source code of hk:
package main
import (
"fmt"
"log"
"os"
)
var (
logger *log.Logger
)
func init() {
f, _ := os.Create("log")
logger = log.New(f, "", log.LstdFlags)
}
func main() {
defer recoverPanic()
panic(fmt.Errorf("This unhandled error will be handled"))
}
func recoverPanic() {
if rec := recover(); rec != nil {
err := rec.(error)
logger.Printf("Unhandled error: %v\n", err.Error())
fmt.Fprintf(os.Stderr, "Program quit unexpectedly; please check your logs\n")
os.Exit(1)
}
}
The output of this program is:
$ ./recover
Program quit unexpectedly; please check your logs
$ echo $?
1
$ cat log
2014/09/21 11:13:11 Unhandled error: This unhandled error will be handled
In this simplified example above, we use a combination of defer and
recover() to handle any exception that might have been thrown with panic(),
log some information about it, and exit the program cleanly.
hk takes this a step further by sending the error up to Rollbar so that all of its unexpected crashes can be examined in aggregate.
All content certified human. LLMs are used for proofreading and corrections, but never to generate prose. Did I make a mistake? Please consider sending a pull request.