CodeNebula
Go🔧Core Languagebeginner

Error Handling

Go · Core Language · Run with go run

Explanation

Go uses explicit error return values instead of exceptions. The `error` interface has one method: `Error() string`. Functions signal failure by returning a non-nil error as their last return value. `fmt.Errorf("context: %w", err)` wraps errors with context; `errors.Is` and `errors.As` unwrap them for inspection.

Real-World Scenario

An HTTP client function returns `(Response, error)`. Each call site decides whether to log-and-continue, retry, or propagate the error up the stack — the decision is explicit at every layer, making error flows easy to audit in code review.

Quick Snippet

snippet.go
import "errors"

var ErrNotFound = errors.New("not found")

func findUser(id int) (*User, error) {
    if id <= 0 {
        return nil, fmt.Errorf("findUser: invalid id %d", id)
    }
    user := db.Lookup(id)
    if user == nil {
        return nil, fmt.Errorf("findUser %d: %w", id, ErrNotFound)
    }
    return user, nil
}

// Caller
user, err := findUser(42)
if errors.Is(err, ErrNotFound) {
    // handle not-found specifically
}

Full Example

error_handling.go
// Compile: go run error_handling.go
// Output:
//   found: Alice
//   findUser -1: findUser: invalid id -1
//   is not-found: true
package main

import (
	"errors"
	"fmt"
)

var ErrNotFound = errors.New("not found")

type User struct{ Name string }

var store = map[int]*User{1: {Name: "Alice"}}

func findUser(id int) (*User, error) {
	if id <= 0 {
		return nil, fmt.Errorf("findUser: invalid id %d", id)
	}
	user, ok := store[id]
	if !ok {
		return nil, fmt.Errorf("findUser %d: %w", id, ErrNotFound)
	}
	return user, nil
}

func main() {
	user, err := findUser(1)
	if err != nil {
		fmt.Println("error:", err)
	} else {
		fmt.Println("found:", user.Name)
	}

	_, err = findUser(-1)
	fmt.Println(err)

	_, err = findUser(99)
	fmt.Println("is not-found:", errors.Is(err, ErrNotFound))
}
Run command
go run error_handling.go