En Go, il existe une approche standard pour la gestion des erreurs via le renvoi d'une valeur de type error à partir d'une fonction. Contrairement aux langages avec des exceptions, en Go, les exceptions (panic, recover) ne sont utilisées que pour des situations réellement exceptionnelles ; pour la logique métier, il est préférable d'utiliser une erreur normale.
Méthode classique :
func doSomething() error { // ... return nil // ou errors.New("some error") } err := doSomething() if err != nil { // traitement de l'erreur }
Vous pouvez créer vos propres types d'erreurs pour une analyse plus détaillée :
type MyError struct { Code int Message string } func (e *MyError) Error() string { return fmt.Sprintf("(%d) %s", e.Code, e.Message) } err := &MyError{404, "not found"}
Vérification typique d'une erreur spécifique :
if myErr, ok := err.(*MyError); ok && myErr.Code == 404 { // traitement de l'erreur 404 }
Peut-on comparer error à nil avec == en Go ?
Réponse : Oui, c'est possible et nécessaire pour vérifier l'absence d'erreur. Mais il est important de se souvenir : si l'erreur a été enveloppée ou créée avec des erreurs contenant nil à l'intérieur des structures, la comparaison peut être incorrecte. Par exemple :
var err error = (*MyError)(nil) fmt.Println(err == nil) // faux !
Une erreur est considérée comme non nulle parce que l'interface n'est pas égale à nil si son type n'est pas nil, même si la valeur à l'intérieur est nil.
Histoire
Un microservice s'occupait de la journalisation des erreurs par comparaison à nil. L'un des développeurs renvoyait une erreur typée comme (*MyError)(nil), sans se rendre compte que cela n'était pas équivalent à nil (l'interface n'est pas nil). En conséquence, le traitement des erreurs ne fonctionnait plus, et de nombreux faux positifs sont apparus dans les métriques.
Histoire
Dans le projet, au lieu de transmettre l'erreur en chaîne, ils utilisaient panic pour toutes les erreurs, considérant cela comme une méthode "propre". Cela a conduit à un plantage de l'application à chaque entrée utilisateur non valide, car panic/recover ne sont pas destinés à la logique métier de flux.
Histoire
L'erreur a été enveloppée plusieurs fois avec fmt.Errorf("some: %w", err), et lors de la vérification d'un type spécifique d'erreur, ils ont effectué une comparaison ordinaire, au lieu d'utiliser errors.Is et errors.As. Cela a conduit à ce que la logique métier ne réagisse pas aux types d'erreurs personnalisées, bien qu'elles étaient réellement présentes dans l'erreur enveloppée.