Passer au contenu principal
eLearner.app
Module 6 · Leçon 5 sur 530/50 dans le cours~14 min
Leçons du module (5/5)

L'interface error

error dans Go n'est pas un mot-clé : c'est une interface intégrée avec un méthode uniquement.

Go
type error interface {
    Error() string
}

Tout ce qui a Error() string est un error. Combiné avec le la convention de retour de (T, error) à partir des fonctions est la base de gestion des erreurs dans Go.

Erreurs Sentinelle

Go
import "errors"

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

func find(key string) (string, error) {
    // ...
    return "", ErrNotFound
}

Une sentinelle est une valeur error exportée que l'appelant peut comparer pour reconnaître un cas précis d’erreur.

Erreurs personnalisées (avec données)

Pour apporter du contexte (par exemple la clé qui manquait) un type est défini :

Go
type ErrNotFound struct {
    Key string
}

func (e *ErrNotFound) Error() string {
    return "non trovato: " + e.Key
}

func find(key string) (string, error) {
    return "", &ErrNotFound{Key: key}
}

erreurs.Est et erreurs.As (Go 1.13+)

Comparez avec == qui ne fonctionne que pour les sentinelles "pures". Être robuste aux erreurs encapsulées, utilisez le package errors :

Go
import "errors"

if errors.Is(err, ErrNotFound) {
    // err È ErrNotFound (anche se wrappato)
}

var nfe *ErrNotFound
if errors.As(err, &nfe) {
    // err È (o wrappa) un *ErrNotFound; nfe punta al valore concreto
    fmt.Println("chiave mancante:", nfe.Key)
}
  • errors.Is(err, target) : vrai s'il y a une cible dans la chaîne d'emballage.
  • errors.As(err, &target) : attribuer pour cibler la première erreur de son type dans la chaîne.

Wrapping avec %w

Go
if err := find("k"); err != nil {
    return fmt.Errorf("operazione X: %w", err)
}

%w (PAS %s ni %v) crée une nouvelle erreur qui enveloppe celle original, en gardant la chaîne navigable à partir de errors.Is/As.

Modèle de gestion

Go
v, err := op()
if err != nil {
    return fmt.Errorf("op fallita per %q: %w", id, err)
}

Expressions idiomatiques :

  • Vérifiez err != nil tout de suite, pas de « premier chemin heureux ».
  • Ajoutez du contexte à chaque couche avec fmt.Errorf("... : %w", err).
  • En amont (près du main / handler), discriminez avec errors.Is/As.

Essayez-le vous-même

Exercice#go.m6.l5.e1
Tentatives : 0Chargement…

Implémentez la chaîne Error() sur *ErrNotFound afin qu'elle renvoie « introuvable : <Key> ».

Chargement de l'éditeur…
Afficher l'indice

`fmt.Println(err)` appelle automatiquement la méthode Error() de votre structure.

Solution disponible après 3 tentatives

Exercice#go.m6.l5.e2
Tentatives : 0Chargement…

Utilisez error.Is pour vérifier si err est égal à la sentinelle ErrEmpty.

Chargement de l'éditeur…
Afficher l'indice

`errors.Is(err, target)` est robuste même avec des chaînes d'emballage.

Solution disponible après 3 tentatives

Quiz#go.m6.l5.e3
Prêt

Quelle est la signature exacte de la méthode pour implémenter l’erreur ?

Go
func (e *MyErr) ??? {}
Options de réponse

Récapitulatif

  • error = interface { Error() string }, intégré.
  • Sentinelles avec errors.New("...") pour les cas connus sans contexte.
  • Types d'erreurs personnalisés avec des champs pour apporter du contexte.
  • errors.Is(err, target) : comparaison robuste avec le packaging.
  • errors.As(err, &target) : extraction type béton.
  • fmt.Errorf("...: %w", err) : emballage qui préserve la chaîne.
  • Ne jamais %v / %s pour l'emballage : utilisez TOUJOURS %w.