Use cases for panic

suggest change

Using of panic in Go should be extremely rare but it does have valid use cases.

Force crash on bad API usage

This is similar to using assert in other languages.

Imagine you're writing a httpGet function that downloads content of the URL.

What should happen when URL is empty string? It's obviously a mistake on the part of the caller.

You can return an error but you can also for a crash with panic:

func httpGet(uri string) ([]byte, error) {
    if uri == "" {
        panic("uri cannot be empty")
    // ... download the url

Sometimes it's better because an error can be ignored or the program might assume that it's a valid error condition, like a website being down.

Forcing a crash increases chances that the developer will look at the problem and fix it.

If you do it often, this helper function will be useful:

func panicIf(cond bool, args ...interface{}) {
	if !cond {
	if len(args) == 0 {
		panic(errors.New("cond failed"))
	format := args[0].(string)
	args = args[1:]
	err := fmt.Errorf(format, args)

Now this can be written as a single line:

func httpGet(uri string) ([]byte, error) {
    panicIf(uri == "", "uri cannot be empty")
    // ... download the url

Function panicIf is flexible. You can call it as:

Simplifying flow control in isolated piece of code

Sometimes it’s easier to propagate an error by panicking and recovering rather than returning errors.

This might be true e.g. in a parser.

When you use that technique, you should observe one rule: panic should not cross public API boundary.

In other words, if you implement a parser library, you should always recover all panics your code creates. Panic used for easier flow control should never reach the caller of your package API.

Protect a program from a crash in a goroutine

Unhandled panic in a goroutine crashes a program.

This is the right behavior most of the time (panic indicates a serious bug and you should fix bugs, not cover them up).

In rare occasions we don't want a single goroutine to bring down the whole program so we can wrap the code with a function that does recover at the top.

This technique is used in Go’s http server package which handles each connection in a separate goroutine. In a web server we don't want a rare bug in request handling code to crash the program.

Feedback about page:

Optional: your email if you want me to get back to you:

Table Of Contents