Skip to content
Errors as Values
step 1/4

Reading — step 1 of 4

Learn

~3 min readInterfaces and Errors

Errors as Values

Go has no exceptions. A function that can fail returns an error as its last result, and the caller decides what to do — right there, in plain control flow:

go

error is just an interface with one method:

go

Anything with an Error() string method is an error. That is the entire mechanism — no hierarchies, no throw, no invisible control flow. The payoff: every failure path is visible in the code, and the compiler complains about an unused err.

Creating errors

go

Wrapping: %w and the error chain

When you pass an error upward, add context. The %w verb (Go 1.13+) formats exactly like %v and records the original error so it can be inspected later:

go

The message is the prefix plus the original, e.g. parse: strconv.Atoi: parsing "abc": invalid syntax. The recorded chain matters because callers can query it without string matching:

go

errors.Is walks the chain comparing values; errors.As walks it looking for a target type. Both only see through links created with %w. Here is the trap: wrap with %v instead and the printed text is identical, but the chain is severed — errors.Is returns false and nobody notices until production. %v and %w print the same but behave differently.

Custom error types

When callers need structured data, define a type:

go

Comparing by string is the anti-idiom

if err.Error() == "not found" breaks the moment a message is reworded or a wrapper adds a prefix. Use sentinels with errors.Is, or types with errors.As. Raw message text belongs in logs — and in graders that diff your program's stdout, like this one.

Your exercise

Write validateAge(s string) (int, error):

  • strconv.Atoi fails: return the error wrapped as fmt.Errorf("parse: %w", err)
  • parsed value is negative: return errors.New("negative")
  • otherwise: return the value and nil

main already prints age: <n> or error: <message>. The grader compares stdout exactly, so the wording is load-bearing:

  1. The prefix must be exactly parse: . For input abc the expected line is error: parse: strconv.Atoi: parsing "abc": invalid syntax. Return the raw error unwrapped and the parse: prefix is missing; invent your own message and nothing matches.
  2. Negative means < 0, not <= 0. The hidden test feeds 0 and expects age: 0. Write if n <= 0 and you reject a perfectly valid age with error: negative.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…

Errors as Values — Go Intermediate