Go a été conçu dès le départ autour du retour explicite des erreurs au lieu des exceptions. Cela permet de développer un code prévisible et d'éviter les pièges cachés courants des constructions try/catch d'autres langages (comme Java ou C++). Une erreur en Go est une interface qui implémente la méthode Error(), ce qui permet de créer des erreurs simples ainsi que des erreurs composées/emballées avec un contexte.
Les problèmes surviennent lors d'un traitement incorrect des erreurs (par exemple, si elles sont ignorées via _ ou non enveloppées d'informations supplémentaires pour le débogage) ou de la création d'erreurs "magiques" qui ne respectent pas l'interface error. Il est également important de savoir retourner des erreurs depuis des fonctions publiques et de les vérifier à chaque appel.
La solution est d'utiliser des approches standard :
Exemple de code :
import ( "errors" "fmt" ) type NotFoundError struct { Resource string } func (e *NotFoundError) Error() string { return fmt.Sprintf("%s introuvable", e.Resource) } func GetUser(id int) (string, error) { if id != 1 { return "", &NotFoundError{"Utilisateur"} } return "Steve", nil } func main() { user, err := GetUser(2) if err != nil { if nfe, ok := err.(*NotFoundError); ok { fmt.Println(nfe.Resource, "problème") } else { fmt.Println("erreur :", err) } } fmt.Println("utilisateur :", user) }
Caractéristiques clés :
Peut-on faire des comparaisons d'erreurs avec ==, ou faut-il utiliser des méthodes spéciales ?
Il est préférable d'utiliser toujours errors.Is() pour comparer avec des erreurs d'emballage, sinon une comparaison avec == peut ne pas fonctionner en cas d'enveloppement d'erreur.
if errors.Is(err, os.ErrNotExist) { // traitement de l'absence de fichier }
Est-il obligatoire d'implémenter un type structure pour une erreur personnalisée, ou est-il suffisant d'utiliser errors.New("...") ?
Si seul le texte de l'erreur est nécessaire, il suffit d'utiliser errors.New(). Si la conservation du contexte est importante (par exemple, le nom de la ressource), il est préférable de définir une structure avec la méthode Error().
Comment retourner correctement une erreur en cas de succès de la fonction ?
En cas de succès, retournez toujours une erreur nulle.
return result, nil
Cas négatif
Un développeur écrit une fonction retournant une erreur sans explication (juste errors.New("échec")). Lors de l'analyse des journaux, il devient impossible de déterminer la cause.
Avantages :
Inconvénients :
Cas positif
Un développeur définit un type d'erreur personnalisé NotFoundError et le retourne avec une description détaillée.
Avantages :
Inconvénients :