Direct naar de hoofdinhoud
eLearner.app
Module 2 · Les 5 van 510/50 in de cursus~12 min
Modulelessen (5/5)

Fouten: het patroon `if err != nil`

In Go, errors are values, not exceptions. A function that can fail returns the error as the last value, and the caller checks it explicitly. It is explicit, predictable, easy to test — the price is a bit more verbosity.

The error interface

error is a small interface built into the language:

Go
type error interface {
    Error() string
}

Any type that implements Error() string is an error.

The fundamental pattern

Go
v, err := operazione()
if err != nil {
    // gestisci o propaga
    return err
}
// usa v

You will see this thousands of times: it is the idiomatic code for every fallible call. Do not feel guilty about the repetition — it is a feature, not a bug.

Building errors: errors.New and fmt.Errorf

Go
import (
    "errors"
    "fmt"
)

err1 := errors.New("file mancante")
err2 := fmt.Errorf("apertura %q fallita: permesso negato", path)

fmt.Errorf is perfect when you want to include variables in the message.

Wrapping with %w

To propagate an error adding context WITHOUT losing the original:

Go
f, err := os.Open(path)
if err != nil {
    return fmt.Errorf("config: %w", err)
}

%w "wraps" the original error, recoverable later with errors.Is (equality for sentinels) or errors.As (for concrete type):

Go
if errors.Is(err, os.ErrNotExist) {
    // file inesistente, gestione speciale
}

Sentinel errors

These are errors exported as variables, used for comparisons with errors.Is:

Go
var ErrNotFound = errors.New("non trovato")

func find(id int) (Item, error) {
    // ...
    return Item{}, ErrNotFound
}

// chiamante:
if errors.Is(err, ErrNotFound) { ... }

panic and recover (preview)

panic exists in Go but is reserved for unrecoverable errors (e.g. bugs, violated invariants), not for normal control flow. We will go deeper in the Functions module with defer/recover. For now: do not use it in place of the if err != nil pattern.

Try it

Oefening#go.m2.l5.e1
Pogingen: 0Laden…

Handle the error from strconv.Atoi: if err != nil, print it and return; otherwise print n.

Editor laden…
Toon hint

The canonical pattern: check `err != nil`, log/return, then use `n`.

Oplossing beschikbaar na 3 pogingen

Oefening#go.m2.l5.e2
Pogingen: 0Laden…

Implement safeDiv: if b == 0 return 0 and an errors.New('divisione per zero'); otherwise a/b and nil.

Editor laden…
Toon hint

Check `b == 0` BEFORE the division to avoid the run-time panic.

Oplossing beschikbaar na 3 pogingen

Quiz#go.m2.l5.e3
Klaar

Which is the idiomatic pattern to handle an error in Go?

Go
v, err := f()
// poi?
Antwoordmogelijkheden

Recap

  • error is an interface with one method Error() string.
  • Canonical pattern: v, err := f(); if err != nil { return err }.
  • Build errors with errors.New(msg) or fmt.Errorf("ctx: %w", err).
  • Use %w for wrapping and errors.Is / errors.As to inspect the chain.
  • panic only for unrecoverable errors, NOT for normal control flow.