Skip to content
Lesson 9 of 14

Step 1 of 5 · Reading · ~3 min

Learn

Functions

Error Handling

Go has no exceptions. A function that can fail returns its failure as an ordinary value, and you check it with an ordinary if. By the end of this lesson you can read a two-value return, decide which of the two values to trust, and write a function of your own that reports failure.

Errors are values

A Go function that can fail returns its result and an error, error last. error is an interface with a single method, Error() string. Today you need exactly one rule about it: nil means it worked, non-nil means it did not.

go

Given "3.95", the call leaves err as nil and price as 3.95, so the program prints 7.9. Given "3,95" (a comma), err is non-nil and the program prints:

cannot read price: strconv.ParseFloat: parsing "3,95": invalid syntax

Notice the geometry: failure bails out early, the happy path carries on un-indented down the left margin. Go code is full of that shape, and you read err != nil the way you read punctuation.

Check the error, not the value

This is the part that costs people an afternoon. When a parse fails, the other return value is not garbage and it is not nil — it is that type's zero value. So a failure and a successful parse of zero look identical:

go

Both calls leave 0 in the number. Only the error can tell them apart:

go

That is why you check the error immediately, before touching the value — not three lines later. The rule holds for every parser in the standard library, the integer one included.

Writing a function that fails

You return errors the same way the standard library does: value first, error last, errors.New for a fixed message and fmt.Errorf when the message needs data.

go

Success returns the answer and nil; failure returns the zero value and a real error. At the call site, the if-with-statement from the conditionals lesson fits perfectly:

go

Message style: lowercase, no trailing punctuation, with context. half 7: not an even number explains itself in a log at 3am; "error" does not.

Common mistakes

  • Branching on the value. Treating a returned 0 as "it failed" reports failure for the perfectly valid input 0. Inputs like 007, which parses to 7, hide the bug because they still look right.
  • Reporting the failure and then carrying on. With no return (or else) after the failure branch, the program prints its complaint and then prints the zero value as well — two lines where exactly one was wanted.
  • Scanning instead of parsing. fmt.Sscan stops at the first character it cannot use, so 12abc comes back as a success holding 12. The strconv parsers reject the whole string instead.
  • Hand-rolling an "are they all digits" check. It rejects +5 and -7, which strconv happily accepts, and it accepts a 22-digit string that cannot fit in an int at all.

Your exercise

Parse one line of input with strconv.Atoi and report either the number or a failure, in the exact words the task specifies. The starter reads the line and strips its newline; what it does not do is decide which of Atoi's two return values answers "did this work?" — and choosing the wrong one is the entire trap.

Up nextSlicesCollections

Discussion

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

Sign in to post a comment or reply.

Loading…