Home
Map
recover, panic, defer ExamplesUse defer functions and the recover built-in to handle errors. Go uses recover, not exception-handling.
Go
This page was last reviewed on Dec 15, 2021.
Recover. Golang provides ways to handle errors. Failure is everywhere—a method might work when we test it, but other conditions might cause it to panic later.
func
With recover, a built-in method, we get errors and can test them. We must specify a call to recover() in a "defer" method. The Go runtime calls these methods when an error occurs.
First example. This program introduces an error-prone method called "divideByZero." It causes an error to occur whenever it is run.
Detail In divideByZero we specify a nested "defer" method. In this func we assign err to the result of recover().
And If err is not nil, we take an action that can repair the program's state and keep it from terminating.
nil
Tip In this program, if we remove the divide by zero error, the value of "dog" will be printed. And the "defer" func will never be called.
package main import "fmt" func divideByZero() { // Use this deferred function to handle errors. defer func() { if err := recover(); err != nil { fmt.Println("HERE") fmt.Println(err) fmt.Println(0) } }() // Cause an error. // ... Go will run the defer func above. cat := 0 dog := 10 / cat fmt.Println(dog) } func main() { // Create a divide by zero error and handle it. divideByZero() }
HERE runtime error: integer divide by zero 0
Panic. This built-in method causes an error to occur. We can handle this error in a defer method that tests the result of recover().
Tip When panic is called, the stack is unwound. And each method is tested for a defer method.
Detail The recover() method returns panic's error. In this program, the WRONG message is provided.
package main import "fmt" func explode() { // Cause a panic. panic("WRONG") } func main() { // Handle errors in defer func with recover. defer func() { if err := recover(); err != nil { // Handle our error. fmt.Println("FIX") fmt.Println("ERR", err) } }() // This causes an error. explode() }
FIX ERR WRONG
Compile-time error. Sometimes a Go developer uses the wrong variable name. For example, I wrote a program that used "string" instead of the identifier "name."
Result The "type string is not an expression" error occurs. Use the correct identifier "name" for a working program.
package main import "fmt" func mistake(name string) { // We put the wrong variable name. // ... Use "name" not string. fmt.Println(string) } func main() { mistake("cat") }
# command-line-arguments C:\programs\file.go:11: type string is not an expression
Performance, defer. The defer keyword has a performance impact. It saves the method call to be called after all returns or panics are executed in a method.
Version 1 This version of the code uses defer to call the Add() function once a return statement is reached in Test.
Version 2 This code does not use defer. It simply calls Add() before each return statement, and does not worry about panics.
Result The code that avoids defer is significantly faster. If panics do not need to be supported, avoiding defer is worth considering.
package main import ( "fmt" "time" ) type Data struct { code int } func Add(data *Data) { data.code++ } func Test(value int, data *Data) int { defer Add(data) if value == 2 { return 3 } return 4 } func TestNoDefer(value int, data *Data) int { if value == 2 { Add(data) return 3 } Add(data) return 4 } func main() { data := new(Data) t0 := time.Now() // Version 1: use defer. for i := 0; i < 200000000; i++ { Test(2, data) } t1 := time.Now() // Version 2: do not use defer. for i := 0; i < 200000000; i++ { TestNoDefer(2, data) } fmt.Println(t1.Sub(t0)) fmt.Println(time.Now().Sub(t1)) }
646.339875ms defer Add 423.013125ms Add
Defer guidelines. If a method is simple, and is known to be reliable, defer is probably not needed and will just slow down the program. If it has file handling, defer is probably worth using.
File
A summary. With recover, defer and panic we handle errors in Go programs. This is an alternative to exception handling (like try and catch in other languages).
C#VB.NETPythonGoJavaSwiftRust
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Dec 15, 2021 (edit link).
Home
Changes
© 2007-2023 Sam Allen.