AnyCompiler

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)
	}
}
Output
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)
	}
}
Output
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.