intermediate18 min

Error Handling

Go's explicit `if err != nil` idiom, and why Go has no exceptions for ordinary errors.

What you'll learn

  • Explain why Go functions return an `error` value instead of throwing exceptions
  • Write the standard `if err != nil` error-check idiom
  • Create a simple error with `errors.New` or `fmt.Errorf`

Explanation

Go deliberately has no exceptions for ordinary error conditions (it does have panic/recover, reserved for truly exceptional, unrecoverable situations, not everyday errors). Instead, a function that can fail returns an error as its last return value: func readConfig() (Config, error).

The standard idiom is immediate, explicit checking: result, err := doSomething(); if err != nil { /* handle it */ }. This makes every possible failure point visible directly in the code, rather than hidden in an invisible exception path that could be thrown from almost anywhere -- a deliberate tradeoff favoring explicitness over brevity.

error is itself just an interface with one method, Error() string. You create a simple one with errors.New("something went wrong"), or a formatted one with fmt.Errorf("failed to load %s: %w", filename, underlyingErr) -- the %w verb specifically "wraps" an existing error so callers can later unwrap and inspect the original cause.

A function returning (result, nil) means success; the convention is that if err is non-nil, the result value should not be trusted or used.

Guided lab

Fill in the blank: the if err != nil idiom

GoNot executed
This lab does not run in your browser or on VisaSparkSchools's servers. Read the code, fill in the missing piece, then reveal the completed code and its expected output.

Fill in the missing error-check condition, then predict the output.

package main

import (
	"errors"
	"fmt"
)

func safeDivide(a, b int) (int, error) {
	if b == 0 {
		return 0, errors.New("division by zero")
	}
	return a / b, nil
}

func main() {
	result, err := safeDivide(10, 0)
	if ____ {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Result:", result)
	}
}

Stuck? Get a hint.

Common mistakes

  • Ignoring a returned error entirely (assigning it to `_` or not checking `err != nil`) and using the result anyway.
  • Reaching for `panic` for ordinary, expected error conditions instead of returning a normal `error` value.
  • Checking `if err == nil` and using it as if the *error* case, forgetting `nil` means success, not failure.

Knowledge check

Knowledge check

1. What does Go use instead of exceptions for ordinary, expected error conditions?
2. What does a `nil` error returned from a function mean?
3. What does the `%w` verb in `fmt.Errorf` do?

Takeaway

Check every returned `error` immediately with `if err != nil` -- Go has no exceptions for ordinary error conditions, so an unchecked error is easy to silently ignore.

Summary

Go functions return errors as normal values, checked explicitly; `errors.New`/`fmt.Errorf` create them, and `%w` wraps an underlying error for later inspection.

References

Your notes

Notes save automatically.

Finished this lesson?

Mark it complete to track your progress and schedule a future review.