Errors
Go has no exceptions for ordinary failures. When a function may not succeed — it cannot find a file, parse a number, or reach the network — it returns the error as an ordinary value: an error is the last item in the result list. The caller receives that value and decides what to do: handle it on the spot, return it upward, or — more rarely — ignore it deliberately. No try/catch, no automatic "bubbling" — the flow of execution stays explicit and linear.
Behind that simplicity sit a few decisions the junior section probes: error is an interface, an ordinary value you can return, store in a variable, and compare with nil; an error is created with errors.New or fmt.Errorf; and panic exists separately — only for genuinely exceptional situations, not for expected failures. This topic walks the basics of error handling layer by layer — from the return idiom to the canonical if err != nil check. The depth of wrapping (%w, errors.Is/errors.As, sentinel errors) is covered by the separate Error Handling topic.
Topic map
- Returning Errors — the
(result, error)idiom: the error is the last returned value;nilmeans success; the caller decides what to do next. errors.New&fmt.Errorf— create an error from text witherrors.New("text")or a formatted one withfmt.Errorf("...: %v", x); the%wverb wraps (deep wrapping lives in go-error-handling).- An Error Is a Value —
erroris a plain interface you return, store, and inspect; unlikepanic, it is not an exception but part of a function's normal result. - The
if err != nilIdiom — check the error immediately after the call and either handle it or return early; don't silence it with_; verbose but explicit control flow.
Common mistakes and traps
| Mistake | Consequence |
|---|---|
Ignoring the returned error with _ | The failure is swallowed silently — value, _ := strconv.Atoi(s) hides invalid input |
Putting error somewhere other than last among return values | Breaks the idiom; readers and linters expect error exactly at the end |
| Expecting a failure to "throw" itself, like an exception | In Go an error does not bubble up — until you explicitly return it upward, it is simply not there |
Using panic for an expected failure (missing file, bad input) | panic is for the exceptional only; an ordinary failure must be an error |
Returning a "blank" result without checking err | When err != nil the result is undefined — reading it before the check is dangerous |
Confusing errors.New and fmt.Errorf | errors.New is fixed text; fmt.Errorf is formatting and wrapping via %w |
Why it matters for interviews
Error handling is the junior-level filter for "understands Go's model" versus "carries habits over from languages with exceptions." The idiom itself is trivial, but the very difference from try/catch is asked almost every time.
What interviewers usually check:
- How a Go function reports a failure and why
erroris the last returned value. - That
erroris an ordinary value (an interface), not a thrown exception, and who decides what to do with it. - How
errors.Newdiffers fromfmt.Errorfand what the%wverb does. - Why a
nilerror means success and why the result must not be read before checkingerr. - How
panic/recoverdiffers from ordinary error handling and whenpanicis appropriate (exceptional cases, not expected failures).