GoSuda

Les raisons pour lesquelles Go a choisi le retour explicite d'erreurs et le mécanisme panic-recover plutôt que le lancement d'exceptions par try-catch

By Rabbit Princess views ...

Go ne prend intentionnellement pas en charge try-catch et ne supporte que la syntaxe panic-recover. Cela suscite le mécontentement de nombreux développeurs habitués à la gestion des erreurs au moyen de try-catch. Alors, pourquoi ne pas avoir intégré try-catch ? La raison en est que try-catch présente plusieurs problèmes.

try-catch-finally

Le bloc try-catch (try-catch) est une structure destinée à traiter les situations d'erreur et les situations exceptionnelles pouvant survenir pendant l'exécution du programme (à l'exécution). Par ailleurs, le bloc finally contient le code qui doit impérativement être exécuté, qu'une exception se soit produite ou non.

Gestion des erreurs et responsabilité

Dans les années 1980 et 1990, la gestion des erreurs était très simple. Les messages d'erreur se limitaient à « disquette pleine », « aucune disquette dans le lecteur » et « absence de droit d'écriture sur la disquette », et les développeurs de cette époque, lorsqu'une erreur survenait, la propageaient par throw jusqu'au point de traitement des erreurs afin de la traiter de manière centralisée. Dans ce contexte, la structure try-catch fonctionnait efficacement.

Toutefois, avec le temps, la situation a changé. La logique métier est devenue complexe, des bases de données et des transactions sont apparues, il a fallu appeler de nombreuses API via le réseau et interpréter une multitude de messages de requête, et enfin, avec l'avènement de la programmation concurrente, il a même fallu traiter les erreurs dans des threads autres que le thread principal.

Les erreurs sont devenues trop complexes pour être traitées en un seul endroit, et aucun point unique ne peut plus assumer la responsabilité de toutes les erreurs. C'est à ce moment qu'un grave problème apparaît avec try-catch.

Le transfert de responsabilité de try-catch

En bref, try-catch est une méthode par laquelle le sujet qui provoque une erreur délègue la responsabilité de cette erreur (le traitement consécutif) à quelqu'un d'autre. Ce destinataire peut être le bloc catch, la méthode parente, la méthode parente de la méthode parente, de la méthode parente… ou quelqu'un d'autre encore. Autrement dit, dans un monde où la gestion des erreurs devient de plus en plus nombreuse et complexe, la solution adoptée par try-catch est précisément « quelqu'un s'en chargera ». Observons le code suivant.

1try {
2    data = readFile("hello.txt");
3    structuredData = parseData(data);
4    insertDBStatus(structuredData[1]);
5    startHTTPServer(structuredData[2]);
6} catch (Exception e) {
7    e.printStackTrace();
8}

Le problème de ce code est qu'il n'est pas clair qui se charge du traitement de printStackTrace, et qu'il est impossible de savoir dans quelle partie du code l'erreur s'est produite. De plus, plus la logique contenue dans l'instruction try est importante, plus le problème devient grave. Paradoxalement, plus le développement se complexifie, plus les développeurs se sont laissé enfermer dans la structure try-catch qui délègue les responsabilités ; ils ont cessé de réfléchir au traitement des erreurs, leur sens des responsabilités s'est affaibli et, finalement, ils ont oublié l'essence même de la gestion des erreurs et des exceptions. Alors, comment Go a-t-il résolu ce problème ?

panic, recover

L'un des atouts de Go est qu'il dispose de divers mécanismes destinés à faire du développeur un bon programmeur plutôt que de l'orienter vers de mauvaises pratiques. panic-recover en est un exemple.

Panic et recover semblent à première vue ne pas différer de try-catch, mais ils s'en distinguent en ce qu'ils ne rejettent pas la responsabilité vers l'extérieur lorsqu'un problème survient. En Go, lorsqu'un panic se produit, il faut le résoudre à l'endroit même où il a été déclenché, plutôt que de transmettre la valeur à l'extérieur. Cela oblige le développeur à assumer la responsabilité de la gestion des erreurs et l'incite à réfléchir plus en profondeur au lieu, à la personne et à la manière de traiter l'erreur en question. C'est en quelque sorte garantir l'autonomie de l'utilisateur tout en lui laissant matière à réflexion.

Par ailleurs, le choix du mot « panic » est également remarquablement judicieux : contrairement à try-recover, le couple panic-recover impose au développeur, rien que par son nom, la pression de n'utiliser ces mécanismes que dans les situations d'erreur manifeste et non dans de simples situations exceptionnelles. Naturellement, le développeur évite d'abuser de recover et ne l'utilise qu'aux endroits nécessaires. Cela contribue grandement à l'écriture de code concis en Go.