La gestion des exceptions est une excellente pratique pour toute méthodologie de développement logiciel. Que ce soit pour un développement basé sur des tests, des sprints agiles ou une session de piratage avec juste une bonne vieille liste de tâches, nous pouvons tous tirer profit de l'assurance que nos bases sont couvertes d'une approche robuste de la gestion des défauts.
Il est primordial de veiller à ce que les erreurs soient corrigées, tout en étant esthétiques et, bien entendu, de ne pas devenir un gros problème logiquement avec des messages cryptés pour que l'utilisateur final puisse en tirer une signification. Si vous faites cela, vous êtes certainement sur la bonne voie pour créer une application solide, stable et collante avec laquelle les utilisateurs aiment travailler et que vous recommanderez vivement..
Idéalement pour nous, Elixir assure une gestion étendue des exceptions via plusieurs mécanismes tels que essayer / attraper
, jette
, et le : erreur, raison
tuple.
Pour afficher une erreur, utilisez élever
dans votre shell interactif pour avoir un avant-goût:
iex> augmenter "Oh noez!" ** (RuntimeError) Oh noez!
Nous pouvons aussi ajouter un type à ceci comme ceci:
iex> raise ArgumentError, message: "message d'erreur ici ..." ** message d'erreur (ArgumentError) ici ...
Certaines des manières dont les erreurs sont traitées dans Elixir peuvent ne pas être évidentes à première vue.
frayer
, nous pouvons créer des processus indépendants. Cela signifie qu'une défaillance sur un thread ne devrait affecter aucun autre processus, sauf en cas de liaison. Mais par défaut, tout restera stable.spawn_link
macro. Il s’agit d’un lien bidirectionnel, ce qui signifie que si un processus lié se termine, un signal de sortie sera déclenché..:Ordinaire
, nous savons que nous avons un problème. Et si on intercepte le signal de sortie avec Process.flag (: trap_exit, true)
, le signal de sortie sera envoyé à la boîte aux lettres du processus, où la logique peut être placée sur la façon de gérer le message, évitant ainsi un crash dur.spawn_links
, mais ce sont des liens unidirectionnels, et nous pouvons les créer avec Process.monitor
. Process.monitor
recevra les messages d'erreur en cas d'échec.Pour un exemple d'erreur, essayez d'ajouter un nombre à un atome et vous obtiendrez ce qui suit:
iex>: foo + 69 ** (ArithmeticError) argument incorrect dans l'expression arithmétique: erlang. + (: foo, 69)
Pour vous assurer que l'utilisateur final ne se trompe pas, nous pouvons utiliser les méthodes try, catch and rescue fournies par Elixir..
Le premier de notre boîte à outils pour la gestion des exceptions est essayer / sauvetage
, qui attrape les erreurs produites en utilisant élever
est donc vraiment mieux adapté pour les erreurs de développement, ou des circonstances exceptionnelles telles que des erreurs de saisie.
essayer / sauvetage
est similaire à un usage essayer / attraper
bloquer que vous avez peut-être vu dans d'autres langages de programmation. Regardons un exemple en action:
iex> try do ...> relance "do failed!" ...> rescue ...> e dans RuntimeError -> IO.puts ("Erreur:" <> e.message) ...> end Erreur: ne réussit pas! :D'accord
Ici nous utilisons le essayer / sauvetage
bloc et le susdit élever
attraper le Erreur d'exécution
.
Cela signifie que le ** (Erreur d'exécution)
sortie par défaut de élever
n'est pas affiché et est remplacé par une sortie plus agréable de la IO.puts
appel.
Il est recommandé d'utiliser le message d'erreur pour donner à l'utilisateur une sortie utile en anglais simple, ce qui l'aide à résoudre le problème. Nous examinerons cela plus en détail dans l'exemple suivant.
Un avantage majeur de Elixir est que vous pouvez obtenir plusieurs résultats dans l’un de ces essayer / sauvetage
des blocs. Regardez cet exemple:
essayez d'essayer |> Keyword.fetch! (: fichier_source) |> File.read! rescue e dans KeyError -> IO.puts "manquant: option source_file" e dans File.Error -> IO.puts "impossible de lire le fichier source" fin
Ici nous avons attrapé deux erreurs dans le porter secours
.
:fichier source
le symbole est manquant. Comme mentionné précédemment, nous pouvons l'utiliser pour créer des messages d'erreur faciles à comprendre pour notre utilisateur final..
Cette approche syntaxique puissante et minimale d’Elixir rend l’écriture de plusieurs vérifications très accessible, ce qui nous permet de vérifier de nombreux points de défaillance possibles, de manière nette et concise. Cela nous aide à nous assurer que nous n’avons pas besoin d’écrire des conditionnelles complexes pour créer des scripts longs qui peuvent être difficiles à visualiser et à déboguer correctement lors d’un développement ultérieur ou à la connexion d’un nouveau développeur..
Comme toujours lorsque vous travaillez à Elixir, KISS est la meilleure approche à adopter..
Il existe des situations dans lesquelles vous devrez exécuter une action spécifique après le blocage try / rescue, qu'il y ait eu une erreur ou non. Pour les développeurs Java ou PHP, vous pouvez penser à la essayer / attraper / enfin
ou de Ruby commencer / secourir / assurer
.
Jetons un coup d'oeil à un exemple simple d'utilisation après
.
iex> essayez de faire>> relance "je veux parler au responsable!" ...> rescue ...> e dans RuntimeError -> IO.puts ("Une erreur est survenue:" <> e.message) ...> après ...> IO.puts "Peu importe ce qui se passe, je me présente toujours comme un gros sou."…> End Une erreur est survenue: je veux parler au responsable! Peu importe ce qui se passe, je me présente toujours comme un mauvais sou. :D'accord
Ici vous voyez le après
être utilisé pour afficher constamment un message (ou cela peut être n'importe quelle fonction que vous souhaitez ajouter).
Une pratique plus courante dans laquelle vous trouverez ceci est l'utilisation d'un fichier, par exemple ici:
: ok, file = File.open "would_defo_root.jpg" try do # Essayez d'accéder au fichier ici après # Assurez-vous de nettoyer ensuite File.close (file) end
Aussi bien que élever
et essayer / attraper
méthodes que nous avons décrites plus tôt, nous avons également les macros lancer et attraper.
En utilisant le jeter
la méthode quitte l'exécution avec une valeur spécifique que nous pouvons rechercher dans notre capture
bloquer et utiliser ensuite comme ceci:
iex> essayez de faire ...> pour x <- 0… 10 do… > si x == 3, faites: lancer (x)…> IO.puts (x)…> fin…> attraper…> x -> "Capturé: # x"…> fin 0 1 2 "Capturé: 3"
Nous avons donc la possibilité de capture
tout ce que nous jeter
à l'intérieur du bloc try. Dans ce cas, le conditionnel si x == 3
est le déclencheur de notre faire: jeter (x)
.
La sortie de l'itération produite à partir de la boucle for nous donne une compréhension claire de ce qui s'est passé par programmation. Progressivement, nous avons avancé et l'exécution a été arrêtée le capture
.
En raison de cette fonctionnalité, il peut parfois être difficile d’imaginer où le jeter
capture
serait mis en œuvre dans votre application. Un lieu privilégié serait l’utilisation d’une bibliothèque dans laquelle l’API n’a pas les fonctionnalités adéquates pour tous les résultats présentés à l’utilisateur, et une capture suffirait pour naviguer rapidement autour du problème, au lieu d’avoir à développer beaucoup plus au sein de la bibliothèque pour gérer la question et le retour approprié pour elle.
Enfin, dans notre arsenal de traitement des erreurs Elixir, nous avons le sortie
. La sortie se fait non pas par la boutique de cadeaux, mais explicitement à la mort du processus..
Les sorties sont signalées comme suit:
iex> spawn_link fn -> exit ("vous avez fini, fils!") end ** (EXIT from #PID<0.101.0>) "tu as fini mon fils!"
Les signaux de sortie sont déclenchés par des processus pour l'une des trois raisons suivantes:
sortie (0)
en C. La raison de sortie pour ce genre de sortie est l'atome :Ordinaire
.essayer / attraper / secourir
bloquer ou lancer / attraper
pour y faire face.:tuer
, qui force le processus de réception à se terminer.À tout moment de la mise à jour sur jeter
, sortie
ou les erreurs
, appeler le System.stacktrace
renverra la dernière occurrence du processus en cours.
La trace de pile peut être assez souvent formatée, mais cela peut changer dans les nouvelles versions d’Elixir. Pour plus d'informations à ce sujet, reportez-vous à la page de manuel.
Pour renvoyer la trace de la pile pour le processus en cours, vous pouvez utiliser les éléments suivants:
Process.info (self (),: current_stacktrace)
Oui, Elixir peut le faire aussi. Bien sûr, vous avez toujours les types intégrés tels que Erreur d'exécution
a ta disposition. Mais ce ne serait pas bien si vous pouviez aller plus loin?
Il est facile de créer votre propre type d'erreur personnalisé en utilisant le défexception
macro, qui acceptera commodément le :message
option, pour définir un message d'erreur par défaut comme ceci:
defmodule MyError do message de defexception: "votre erreur personnalisée s'est produite" end
Voici comment l'utiliser dans votre code:
iex> essayez de faire> relancez MyError ...> rescue ...> e dans MyError -> e ...> end% MyError message: "votre erreur personnalisée s'est produite"
La gestion des erreurs dans un langage de méta-programmation tel qu'Elixir a de nombreuses implications potentielles sur la façon dont nous concevons nos applications et les rendons suffisamment robustes pour permettre un traitement rigoureux de l'environnement de production..
Nous pouvons nous assurer que les utilisateurs finaux disposent toujours d'un indice: un message d'orientation simple et facile à comprendre, qui ne rendra pas leur tâche plus difficile, mais plutôt l'inverse. Les messages d'erreur doivent toujoursêtre écrit en anglais simple et donner beaucoup d'informations. Les codes d'erreur cryptiques et les noms de variables ne sont pas bons pour les utilisateurs moyens, et peuvent même dérouter les développeurs!
À l'avenir, vous pouvez surveiller les exceptions générées dans votre application Elixir et configurer une journalisation spécifique pour certains points problématiques. Vous pourrez ainsi analyser et planifier votre solution ou utiliser une solution prête à l'emploi..
Améliorez la précision de nos travaux de débogage et permettez à la surveillance de la stabilité de vos applications de suivre ces services tiers disponibles pour Elixir:
À l'avenir, vous voudrez peut-être étendre davantage les capacités de traitement des erreurs de votre application et rendre votre code plus facile à lire. Pour cela, je vous recommande de consulter ce projet pour une gestion élégante des erreurs sur GitHub..
!