En Go, l'approche standard est de gérer les erreurs via la valeur de retour error. Cela permet de contrôler explicitement ce qu'il faut faire en cas d'erreur à chaque point. Panic est un mécanisme pour gérer des situations catastrophiques imprévues : elle interrompt l'exécution jusqu'au prochain defer, où recover peut être utilisé pour "sauver". Mais recover ne fonctionne que dans defer.
Meilleures pratiques :
func safeDivide(a, b int) (int, error) { if b == 0 { return 0, errors.New("divide by zero") } return a/b, nil } func mustDivide(a, b int) int { if b == 0 { panic("divide by zero!") } return a/b }
Peut-on "attraper" n'importe quelle panique d'erreur avec recover à n'importe quel endroit du programme ?
Réponse : Non, recover ne fonctionne que dans defer et uniquement dans la même goroutine où la panique est déclenchée. Dans d'autres cas, la panique terminera l'exécution de cette (ou de toutes) goroutines — cela devient souvent une surprise.
Histoire
Dans l'API REST, on a utilisé panic pour gérer des erreurs normales dans la logique métier. Cela a conduit à des plantages non évidents de l'application et à des logs incorrects, car recover ne fonctionnait pas toujours correctement.
Histoire
Dans le service de traitement des paiements, un defer + recover a été implémenté dans la fonction principale pour "attraper" toutes les panique, mais on a oublié les goroutines — dans les goroutines filles sans defer/recover, l'application plantait avec des erreurs "terribles", laissant certaines transactions dans un état incohérent.
Histoire
Dans le parseur de structures complexes, on a oublié de faire le retour d'erreur, on l'a remplacé par panic — cela a compliqué la maintenance et les tests, il a fallu réécrire complètement le traitement des erreurs pour avoir un logging détaillé et une expérience utilisateur correcte.