Leçons du module (5/5)
Erreurs : le motif `if err != nil`
Dans Go, les erreurs sont des valeurs, pas des exceptions. Une fonction qui peut fail renvoie l'erreur comme dernière valeur et l'appelant la vérifie explicitement. C'est explicite, prévisible, facile à tester — le prix est un peu plus de verbosité.
L'interface error
error est une petite interface intégrée au langage :
type error interface {
Error() string
}Tout type qui implémente Error() string est un error.
Le modèle fondamental
v, err := operazione()
if err != nil {
// gestisci o propaga
return err
}
// usa vVous le verrez des milliers de fois : c'est le code idiomatique de chaque appel faillible. Ne vous sentez pas coupable de la répétition - c'est une caractéristique, pas un bug.
Erreurs de construction : errors.New et fmt.Errorf
import (
"errors"
"fmt"
)
err1 := errors.New("file mancante")
err2 := fmt.Errorf("apertura %q fallita: permesso negato", path)fmt.Errorf est parfait lorsque vous souhaitez inclure des variables dans le message.
Emballage avec %w
Pour propager une erreur en ajoutant du contexte SANS perdre l'original :
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("config: %w", err)
}%w "enveloppe" l'erreur d'origine, récupérable ultérieurement avec
errors.Is (égalité pour les sentinelles) ou errors.As (pour le type béton) :
if errors.Is(err, os.ErrNotExist) {
// file inesistente, gestione speciale
}Erreurs Sentinelle
Il s'agit d'erreurs exportées sous forme de variables, utilisées pour les comparaisons avec errors.Is :
var ErrNotFound = errors.New("non trovato")
func find(id int) (Item, error) {
// ...
return Item{}, ErrNotFound
}
// chiamante:
if errors.Is(err, ErrNotFound) { ... }panic et recover (aperçu)
panic existe dans Go mais est réservé aux erreurs irrécupérables (ex. bugs,
invariants violés), pas pour le flux de contrôle normal. Nous approfondirons
le module Fonctions avec defer/recover. Pour l'instant : ne l'utilisez pas sur place
du modèle if err != nil.
Essayez-le
Gérez l'erreur de strconv.Atoi : si err != nil, imprimez-la et retournez ; sinon, imprimez n.
Afficher l'indice
Le modèle canonique : vérifiez `err != nil`, log/return, puis utilisez `n`.
Solution disponible après 3 tentatives
Implémentez safeDiv : si b == 0, retournez 0 et un error.New('divisione per zero'); sinon a/b et nul.
Afficher l'indice
Vérifiez `b == 0` AVANT la division pour éviter la panique à l'exécution.
Solution disponible après 3 tentatives
Quel est le modèle idiomatique pour gérer une erreur dans Go ?
v, err := f()
// poi?Récapitulatif
errorest une interface avec une seule méthodeError() string.- Modèle canonique :
v, err := f(); if err != nil { return err }. - Générez des erreurs avec
errors.New(msg)oufmt.Errorf("ctx: %w", err). - Utiliser
%wpour l'emballage eterrors.Is/errors.Aspour inspecter la chaîne. panicuniquement pour les erreurs irrécupérables, PAS pour le flux de contrôle normal.