Dans l’écosystème Go, la manière dont les erreurs sont gérées diffère fondamentalement de celle des langages comme Java ou Python. Alors que ces derniers attachent automatiquement une pile d’appels (stack trace) à chaque exception, Go laisse au développeur le soin d’enrichir manuellement ses erreurs avec du contexte au fil de la propagation. En théorie, cette approche, appelée « trace logique », offre un message lisible par un humain et complet même à travers des changements de goroutines. En pratique, elle impose une charge mentale et une maintenance continues que la plupart des équipes peinent à assumer.

Traces logiques : le récit que l’on écrit à la main

Le mécanisme standard en Go consiste à utiliser fmt.Errorf ou des bibliothèques équivalentes pour envelopper une erreur d’un message décrivant l’étape en cours. Par exemple, une erreur de connexion à une base de données peut remonter sous la forme : « unable to get user: failed to query users table: connection refused ». Ce message constitue une trace logique qui, si elle est tenue à jour, permet de comprendre le chemin emprunté par l’erreur sans avoir à lire une pile d’appels complète.

L’avantage est double : la trace est directement compréhensible par un humain et elle reste cohérente même lorsque l’erreur traverse des canaux, des goroutines ou d’autres points de passage qu’une pile d’appels classique perdrait. Cependant, ce bénéfice ne se maintient qu’au prix d’une révision constante des messages d’enveloppement à chaque évolution du code, à l’image des commentaires qui peuvent devenir obsolètes.

Le fossé entre la théorie et la pratique

Dans la réalité des projets clients, l’auteur de l’article constate que la plupart des équipes ne parviennent pas à suivre cet effort de maintenance, et parfois même n’en mesurent pas l’existence. Les erreurs produites en production deviennent alors trop imprécises pour être diagnostiquées. À l’opposé, une pile d’appels obtenue automatiquement, comme celle générée par Java, ne nécessite aucune intervention humaine pour être exacte et complète dans le fil d’exécution où l’erreur survient.

Une solution intermédiaire : ajouter systématiquement la pile d’appels

Face à ce constat, une approche pragmatique est proposée. Plutôt que de renoncer entièrement aux traces logiques ou de les considérer comme suffisantes, il est recommandé d’ajouter une pile d’appels à chaque erreur nouvellement créée ou à la première rencontre d’une erreur provenant d’une bibliothèque tierce. Cela garantit que toute erreur dans une application Go contient automatiquement une pile d’appels, avec un effort minimal et sans charge cognitive.

Le développeur reste libre d’ajouter du contexte supplémentaire lorsqu’il le juge utile, mais cette étape n’est plus critique pour la débogabilité. Une simple erreur « connection refused » devient ainsi exploitable si elle est accompagnée d’une pile d’appels indiquant les fonctions getUser et greetUser. L’implémentation de ce mécanisme ne nécessite pas obligatoirement une bibliothèque externe. La bibliothèque github.com/pkg/errors, conçue par Dave Cheney, reste une option documentée pour ceux qui préfèrent ne pas développer leur propre solution, bien qu’elle soit en mode maintenance depuis que certaines de ses fonctionnalités ont été intégrées à la bibliothèque standard. cockroachdb/errors est également citée comme une alternative activement maintenue.

Un choix de conception qui a un coût

En définitive, le choix entre trace logique et pile d’appels n’est pas binaire. Les deux servent à attacher du contexte aux erreurs pour permettre leur compréhension ultérieure. La trace logique offre un contexte plus riche mais impose un coût de maintenance élevé ; la pile d’appels fournit un contexte moins spécifique mais fiable et sans effort. La recommandation pour la majorité des équipes est d’adopter une approche médiane, où la pile d’appels constitue la base garantie, et où le contexte additionnel reste une option laissée à l’appréciation du développeur. Cette stratégie vise à éviter que les erreurs en production ne deviennent des boîtes noires impossibles à diagnostiquer.