Error Fundamentals in Go

The basics of Go errors - the error interface, returning and checking errors with if err != nil, and creating errors with errors.New and fmt.Errorf.

Go treats a failure as a normal value that a function returns, not as an exception that jumps up the call stack. Once that idea clicks, the rest of Go error handling is mostly a set of habits built on top of it. This section covers the three foundations: what an error value is, how to return and check one, and how to create your own.

The error Interface

error is a built-in interface with one method, Error() string. Any type with that method is an error, and nil means no error.

n, err := strconv.Atoi("42x")
if err != nil {
	fmt.Println(err) // strconv.Atoi: parsing "42x": invalid syntax
}

Functions that can fail return error as their last result. You check it right after the call and never use the other results until you know err is nil.

Returning and Checking Errors

Your own functions follow the same contract: return zero values plus an error on failure, and the real result plus nil on success.

func divide(a, b float64) (float64, error) {
	if b == 0 {
		return 0, errors.New("cannot divide by zero")
	}
	return a / b, nil
}

Callers check each error and return early, which keeps the success path flat and easy to read.

Check before you use:

Using a result before checking its error is the most common source of nil pointer dereference panics in beginner Go code.

Creating Errors with errors.New and fmt.Errorf

errors.New("insufficient funds") creates an error with a fixed message. fmt.Errorf("user %d not found", id) builds one with details in it, and fmt.Errorf("load config: %w", err) adds context to an error you received while keeping the original reachable.

Summary

These three pages give you everything needed to write correct Go error handling for small programs. The later sections build on them: wrapping and inspecting errors, designing error types for your packages, and handling errors in real programs like HTTP servers and file readers.

The error Interface in Go

What an error is in Go, how the built-in error interface works, and why Go returns errors as values instead of throwing exceptions.

Returning and Checking Errors in Go

How to return errors from your own functions, check them with if err != nil, and keep error handling readable with early returns.

Creating Errors with errors.New and fmt.Errorf

The two everyday ways to create an error in Go, when to use each, and how to put useful details like IDs and file names into the message.