Maison > développement back-end > Golang > Arrêtez tôt pour gagner !

Arrêtez tôt pour gagner !

Mary-Kate Olsen
Libérer: 2024-12-25 20:32:08
original
898 Les gens l'ont consulté

Quitting early for the win!

Résumé très court : quitter votre programme lorsque vous obtenez une erreur peut être une bonne idée. Utiliser gobail vous facilitera la vie.

Lorsque vous obtenez une erreur dans votre code Go, vous verrez normalement quelque chose comme ceci :

err := myFunc()
if err != nil {
    return fmt.Errorf("doing my thing: %w", err)
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Vous remarquerez quelques éléments dans cet exemple :

  1. Vous devez vérifier s'il y a une erreur
  2. Il y a du texte qui aidera à diagnostiquer l'erreur
  3. Et l'erreur est enveloppée, renvoyée avec le texte

Alors, que se passe-t-il ensuite ? Eh bien, tout se reproduit. Vous vérifiez la valeur de l'erreur, la décrivez, la renvoyez. Et puis tout recommence.

Pourquoi faisons-nous cela ? Pourquoi tous ces efforts ?

Eh bien, tout dépend du logiciel que vous écrivez. Lorsque vous obtenez une erreur, vous devez prendre une décision. Qu'arrive-t-il à cette erreur ?

Si vous écrivez une API HTTP répondant à une requête, vous finirez par accéder à une sorte de gestionnaire HTTP et vous transformerez cette erreur en une réponse - peut-être un petit 400 avec un format de rappel poli. demande correctement ou éventuellement un 500 et un message inquiétant sur la santé de votre application. Alternativement, si vous écrivez une sorte d’outil CLI, vous pouvez décider que l’erreur finira par être transmise à votre fonction principale. Quel que soit le type de programme, vous pouvez décider que cela suffit : le programme doit simplement se terminer car vous ne pouvez rien faire d'autre.

Regardons cette dernière option. Quand est-il approprié de simplement quitter votre programme ? Voici quelques raisons auxquelles je peux penser :

a. Il n'y a rien d'autre à faire, l'erreur est si grave que tout doit s'arrêter maintenant
b. Il n'y a aucune conséquence à la fin du programme (aucun nettoyage n'est requis, aucun statut avec lequel répondre)
c. Il est souhaitable de s'arrêter tôt, vous disposez peut-être d'un moniteur qui redémarre le processus proprement

Quelle que soit la raison, vous devez réfléchir à la manière dont vous allez sortir proprement. Maintenant, la première chose que vous allez probablement essayer est la suivante :

err := myFunc()
if err != nil {
    fmt.Printf("doing my thing: %v", err)
    os.Exit(1)
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Il ressemble assez à notre code de gestion des erreurs d'origine, mais avec quelques différences importantes. La première est assez évidente : il y a une superbe déclaration stop-right-g*****n-now ici. Votre programme ne va pas continuer. Le deuxième point est peut-être plus important. Le code qui appelle cet exemple ne se soucie pas de gérer les erreurs. Il n'y a aucun chemin de code supplémentaire à tester - nous pouvons être sûrs que le code appelant n'a pas de bloc if à tester car il n'y a rien de retourné que nous devons vérifier.

Tester vos sorties

J'étais donc peut-être un peu enthousiaste lorsque je vous ai suggéré de simplement avoir confiance que votre code de sortie fonctionnera. Vous devriez probablement vérifier que la raison pour laquelle votre nouveau programme s'est arrêté est pour la bonne raison.

Tentative 1 : exécutez simplement votre programme

J'ai l'impression que cela devrait être facile. Voici quelques éléments à considérer : dans le cas le plus simple, vous allez simplement exécuter votre programme et déclencher une condition d’erreur. Par exemple, demandez à votre outil CLI d'ouvrir un fichier qui n'existe pas. Vous pouvez le faire manuellement pour quelques cas simples. Lorsque le nombre de tests augmente, vous aurez probablement besoin d'une sorte d'automatisation pour vous aider.

Remarque rapide : c'est probablement le sujet d'un tout autre article de blog, mais ma façon préférée actuelle de tester les outils CLI utilise godog pour écrire des tests. Cela peut être un peu complexe mais je l'ai trouvé extrêmement puissant. Voici quelques bons exemples de la façon dont je l'ai abordé avec layli et wait-for.

Cette approche vous mènera très loin, mais il peut parfois être difficile de créer les conditions qui exerceront correctement tous les chemins de code sur lesquels vous voulez avoir confiance.

Tentative 2 - simuler la sortie

OK, nous allons maintenant utiliser certaines fonctionnalités du langage Go. Nous n'avons pas réellement besoin d'appeler os.Exit - nous pouvons appeler quelque chose qui y ressemble. Alors regarde ça :

err := myFunc()
if err != nil {
    return fmt.Errorf("doing my thing: %w", err)
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Alors comment allons-nous en profiter pour nos tests ? Comme la fonction a maintenant été transformée en variable (customExit), nous pouvons alors remplacer la valeur par quelque chose d'autre que nous voulons faire. Comme ça...

err := myFunc()
if err != nil {
    fmt.Printf("doing my thing: %v", err)
    os.Exit(1)
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Il s'agit d'une approche beaucoup plus conviviale pour les tests unitaires. Vous pouvez vérifier que le code de sortie utilisé est correct - et que vous avez réellement appelé la fonction de sortie.

En apparence, cela a l'air génial, mais il y a un gros problème : si votre test réussit, alors votre programme continuera et exécutera le reste de la fonction lorsque vous vous attendiez à ce qu'elle se termine. Cela continuera même si la configuration du test signifie que le reste de l'exécution n'est pas valide et causera des problèmes pour vos tests, comme provoquer des paniques.

Suppression du code pour supprimer des tests

Eh bien, cela semble un peu extrême !

J'ai l'impression que je devrais expliquer... Généralement, dans les entreprises « bien gérées », vous devez vous assurer que chaque ligne de code a fait ses preuves avant de pouvoir être présentée à vos clients. En utilisant les techniques ci-dessus, vous ne pourrez peut-être pas générer les mesures de couverture correctes pour attester que vous êtes bon. Même si c'est trivial de raisonner.
Tous les exemples ci-dessus supposent que lorsque nous obtenons une erreur, nous devons la vérifier pour décider quoi faire (Quitter avec vengeance). Ne serait-ce pas génial si nous pouvions sortir sans avoir à vérifier qu'il y a eu une erreur ?

Voyons ce que nous pouvons faire.

err := myFunc()
if err != nil {
    return fmt.Errorf("doing my thing: %w", err)
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Jetez un œil à l’exemple ci-dessus. La fonctionnalité est la même mais l’implémentation de myFunc est désormais beaucoup plus simple – il n’y a pas de conditions. Nous pouvons vérifier l'implémentation de la fonction checkExit dans ses propres tests, ce qui signifie que tout ce qui est nouveau dans myFunc() peut être vérifié beaucoup plus facilement.

Présentation de Gobail

Une nouvelle bibliothèque, gobail, a été créée pour vous permettre d'être sûr que s'il y a une erreur, elle sera traitée sans avoir à ajouter de complexité à votre propre code. Cela ressemble à ceci :

err := myFunc()
if err != nil {
    fmt.Printf("doing my thing: %v", err)
    os.Exit(1)
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cette bibliothèque a été entièrement testée, avec des métriques de couverture, pour le prouver. Vous pouvez l'utiliser en toute sécurité sans avoir à craindre qu'une erreur soit ignorée. Il gérera également les fonctions avec 2 valeurs de retour, comme ceci :

type ExitFunc func(code int)

var customExit ExitFunc = os.Exit

func myFunc() {
    err := someOtherFunc()
    if err != nil {
        fmt.Printf("doing my thing: %v", err)
        customExit(1)
    }
}
Copier après la connexion

Notez également que vous incluez l'erreur qui est à l'origine de tous vos problèmes.

Il est également possible de paniquer au lieu de quitter, en imprimant notre trace de pile et d'autres informations contextuelles du programme lorsque la panique est invoquée. Jetez un œil à la documentation pour plus de détails.

Isoler les dépendances

En écrivant un logiciel avec gobail, vous remarquerez que vous devrez principalement l'utiliser pour parler à des bibliothèques externes. Le code supplémentaire que vous devez généralement écrire pour gérer tous les cas d'erreur peut être enveloppé dans un appel à Return ou Return2 et supposer que nous quitterons si nécessaire.

Conclusion

Parfois, il est souhaitable de quitter votre programme au lieu de gérer vos erreurs en détail. La bibliothèque gobail a été créée et validée pour que vous n'ayez pas à vous soucier des détails de la preuve.

Si vous trouvez une amélioration qui pourrait être apportée ou si vous avez simplement une suggestion, soulevez un PR ou un problème sur le dépôt et les développeurs s'y mettront dès qu'ils le pourront !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal