Créer des erreurs personnalisées
errors.New, fmt.Errorf et erreurs sentinelles
Créer des erreurs personnalisées est une leçon Go Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Go Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Go Academy comprend 4 leçons au total.
Pourquoi créer des types d'erreur personnalisés ?
Les types d'erreur personnalisés transportent des données structurées au-delà d'un message textuel, ce qui permet aux appelants d'examiner des conditions d'erreur précises et d'y réagir :
package main
import "fmt"
// Custom error type carries extra context
type HTTPError struct {
StatusCode int
Message string
}
func (e *HTTPError) Error() string {
return fmt.Sprintf("HTTP %d: %s", e.StatusCode, e.Message)
}
func fetch(url string) error {
return &HTTPError{404, "page not found"}
}
func main() {
err := fetch("http://example.com")
fmt.Println(err) // HTTP 404: page not found
}Implémenter l'interface error
Tout type possédant une méthode Error() string satisfait l'interface error :
package main
import "fmt"
type ValidationError struct {
Field string
Value interface{}
Message string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("validation: field %q value %v — %s", e.Field, e.Value, e.Message)
}
func validateAge(age int) error {
if age < 0 || age > 150 {
return &ValidationError{"age", age, "must be between 0 and 150"}
}
return nil
}
func main() {
fmt.Println(validateAge(-5))
}Erreurs sentinelles avec errors.New
Les erreurs sentinelles sont des variables définies au niveau du paquet pour représenter des conditions d'erreur connues :
package main
import ("fmt"; "errors")
var (
ErrNotFound = errors.New("not found")
ErrUnauthorized = errors.New("unauthorized")
ErrAlreadyExists = errors.New("already exists")
)
func getUser(id int) (string, error) {
if id != 1 { return "", ErrNotFound }
return "Alice", nil
}
func main() {
_, err := getUser(99)
if errors.Is(err, ErrNotFound) {
fmt.Println("user does not exist")
}
}fmt.Errorf avec %w pour encapsuler
fmt.Errorf avec %w encapsule une erreur tout en préservant l'originale pour errors.Is et errors.As :
package main
import ("fmt"; "errors")
var ErrDatabase = errors.New("database error")
func queryDB() error {
return fmt.Errorf("queryDB: %w", ErrDatabase)
}
func main() {
err := queryDB()
fmt.Println(err) // queryDB: database error
fmt.Println(errors.Is(err, ErrDatabase)) // true — unwrapped
}Erreur personnalisée avec Unwrap
Implémentez Unwrap() error sur votre type d'erreur personnalisé pour qu'il participe aux chaînes d'erreurs :
package main
import ("fmt"; "errors")
var ErrNotFound = errors.New("not found")
type QueryError struct {
Query string
Err error
}
func (e *QueryError) Error() string {
return fmt.Sprintf("query %q: %v", e.Query, e.Err)
}
func (e *QueryError) Unwrap() error { return e.Err }
func main() {
err := &QueryError{"SELECT *", ErrNotFound}
fmt.Println(err)
fmt.Println(errors.Is(err, ErrNotFound)) // true
}errors.Is — vérification de l'identité
errors.Is parcourt la chaîne d'erreurs à la recherche d'une erreur égale à la cible :
package main
import ("fmt"; "errors")
var ErrTimeout = errors.New("timeout")
func deepCall() error {
return fmt.Errorf("layer3: %w", fmt.Errorf("layer2: %w", ErrTimeout))
}
func main() {
err := deepCall()
fmt.Println(errors.Is(err, ErrTimeout)) // true — found deep in chain
}errors.As — extraction d'un type
errors.As recherche dans la chaîne la première erreur correspondant à un type cible et l'y affecte :
package main
import ("fmt"; "errors")
type PermissionError struct{ User string }
func (e *PermissionError) Error() string { return "permission denied for " + e.User }
func action(user string) error {
return fmt.Errorf("action: %w", &PermissionError{user})
}
func main() {
err := action("bob")
var pe *PermissionError
if errors.As(err, &pe) {
fmt.Println("denied:", pe.User) // denied: bob
}
}Encapsulation de plusieurs erreurs (Go 1.20 et versions ultérieures)
Go 1.20 a ajouté errors.Join et fmt.Errorf avec plusieurs %w pour regrouper les erreurs :
package main
import ("fmt"; "errors")
func validate(name, email string) error {
var errs []error
if name == "" { errs = append(errs, errors.New("name required")) }
if email == "" { errs = append(errs, errors.New("email required")) }
return errors.Join(errs...)
}
func main() {
err := validate("", "")
fmt.Println(err)
// name required
// email required
}Conventions de nommage des types d'erreur
Conventions concernant les variables et les types d'erreur en Go :
- Variables d'erreur sentinelle :
ErrXxx(par exempleErrNotFound) - Types d'erreur personnalisés :
XxxError(par exempleValidationError) - Variable de paquet pour une erreur sentinelle, type pointeur pour les erreurs riches
- Exportez-les pour que les appelants puissent les utiliser avec
errors.Is/errors.As
Quand utiliser chaque approche
Choisir la bonne approche pour les erreurs :
errors.New— simple, sans données supplémentaires, pour vérifier l'identité d'une erreur sentinellefmt.Errorf— message formaté avec encapsulation facultative- Type personnalisé — lorsque l'appelant a besoin de données structurées (champs, codes)
errors.Join— pour regrouper plusieurs erreurs de validation
Vérification rapide
Quelle fonction permet d'extraire un type d'erreur précis d'une chaîne d'erreurs ?
Récapitulatif : erreurs personnalisées
Résumé :
- Implémentez
Error() stringpour créer des types d'erreur personnalisés - Ajoutez
Unwrap() errorpour participer aux chaînes d'erreurs - Utilisez
errors.Ispour vérifier l'identité eterrors.Aspour extraire un type - Erreurs sentinelles :
ErrXxx; types personnalisés :XxxError errors.Joinregroupe plusieurs erreurs (Go 1.20 et versions ultérieures)
Questions Fréquemment Posées
La leçon « Créer des erreurs personnalisées » est-elle gratuite ?
Oui — le texte complet de « Créer des erreurs personnalisées » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Go Academy, passe à CoddyKit PRO. Le cours Go Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Créer des erreurs personnalisées » ?
errors.New, fmt.Errorf et erreurs sentinelles Tu pratiques Go Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Go Academy ?
Aucune expérience préalable n'est requise. Go Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Créer des erreurs personnalisées » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Go Academy ?
Oui. Chaque leçon Go Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- L’interface error
- Créer des erreurs personnalisées
- Encapsuler et désencapsuler les erreurs
- panic, recover et defer