Error Handling
Go has no try/catch and no exceptions for ordinary error handling. Instead, a function that can fail simply returns an error as an extra value, and the caller checks it explicitly — error is just an interface with one method, Error() string.
package main
import (
"errors"
"fmt"
)
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("cannot divide by zero")
}
return a / b, nil
}
func main() {
result, err := divide(10, 2)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Result:", result)
}
}Result: 5
Checking err is not optional, by convention
if err != nil immediately after a call that returns an error is one of the most common patterns in any Go codebase. There's no language-level enforcement, but idiomatic Go code checks every error it gets back, right where it's returned.
package main
import (
"errors"
"fmt"
)
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("cannot divide by zero")
}
return a / b, nil
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Result:", result)
}
}Error: cannot divide by zero
Next: defer, panic, and recover — Go's narrow, deliberately-limited exception-like mechanism.
Practice exercise
Write a function safeDivide(a, b float64) (float64, error) that returns an error "cannot divide by zero" if b is 0, otherwise a/b and nil. Call it with (10, 0), and print the error if there is one.