Erlang - Exceptions

La gestion des exceptions est requise dans tout langage de programmation pour gérer les erreurs d'exécution afin que le flux normal de l'application puisse être maintenu. L'exception perturbe normalement le flux normal de l'application, ce qui explique pourquoi nous devons utiliser la gestion des exceptions dans notre application.

Normalement, lorsqu'une exception ou une erreur se produit à Erlang, le message suivant s'affiche.

{"init terminating in do_boot", {undef,[{helloworld,start,[],[]}, 
{init,start_it,1,[]},{init,start_em,1,[]}]}}

Le vidage sur incident sera écrit dans -

erl_crash.dump
init terminating in do_boot ()

À Erlang, il existe 3 types d'exceptions -

  • Error - Appel erlang:error(Reason)mettra fin à l'exécution dans le processus en cours et inclura une trace de pile des dernières fonctions appelées avec leurs arguments lorsque vous l'attraperez. Ce sont les types d'exceptions qui provoquent les erreurs d'exécution ci-dessus.

  • Exists- Il existe deux types de sorties: les sorties «internes» et les sorties «externes». Les sorties internes sont déclenchées en appelant la fonctionexit/1et faire en sorte que le processus en cours arrête son exécution. Les sorties externes sont appelées avecexit/2 et ont à voir avec de multiples processus dans l'aspect simultané d'Erlang.

  • Throw- Un throw est une classe d'exception utilisée pour les cas que le programmeur peut s'attendre à gérer. En comparaison avec les sorties et les erreurs, ils ne comportent pas vraiment de "crash ce processus!" l'intention derrière eux, mais plutôt ils contrôlent le flux. Lorsque vous utilisez les lancers en vous attendant à ce que le programmeur les gère, il est généralement judicieux de documenter leur utilisation dans un module qui les utilise.

UNE try ... catch est un moyen d'évaluer une expression tout en vous permettant de gérer le cas réussi ainsi que les erreurs rencontrées.

La syntaxe générale d'une expression try catch est la suivante.

Syntaxe

try Expression of 
SuccessfulPattern1 [Guards] -> 
Expression1; 
SuccessfulPattern2 [Guards] -> 
Expression2 

catch 
TypeOfError:ExceptionPattern1 -> 
Expression3; 
TypeOfError:ExceptionPattern2 -> 
Expression4 
end

L'expression entre les deux try and ofest dit protégé. Cela signifie que tout type d'exception se produisant dans cet appel sera intercepté. Les modèles et expressions entre lestry ... of and catch se comportent exactement de la même manière qu'un case ... of.

Enfin, la partie catch - ici, vous pouvez remplacer TypeOfErrorpar erreur, lancer ou quitter, pour chaque type respectif que nous avons vu dans ce chapitre. Si aucun type n'est fourni, un jet est supposé.

Voici quelques-unes des erreurs et les raisons d'erreur dans Erlang -

Erreur Type d'erreur
Badarg Mauvais argument. L'argument est d'un type de données incorrect ou est mal formé.
Badarith Mauvais argument dans une expression arithmétique.
{badmatch, V} L'évaluation d'une expression de correspondance a échoué. La valeur V ne correspond pas.
clause_fonction Aucune clause de fonction correspondante n'est trouvée lors de l'évaluation d'un appel de fonction.
{case_clause, V} Aucune branche correspondante n'est trouvée lors de l'évaluation d'une expression de cas. La valeur V ne correspond pas.
if_clause Aucune vraie branche n'est trouvée lors de l'évaluation d'une expression if.
{try_clause, V} Aucune branche correspondante n'est trouvée lors de l'évaluation de la section of d'une expression try. La valeur V ne correspond pas.
undef La fonction est introuvable lors de l'évaluation d'un appel de fonction.
{badfun, F} Quelque chose ne va pas avec un F amusant
{badarity, F} Un plaisir est appliqué au mauvais nombre d'arguments. F décrit le plaisir et les arguments.
timeout_value La valeur du délai d'expiration dans une expression receive..after est évaluée à autre chose qu'un entier ou l'infini.
noproc Essayer de se lier à un processus inexistant.

Voici un exemple de la façon dont ces exceptions peuvent être utilisées et comment les choses sont faites.

  • La première fonction génère tous les types d'exception possibles.

  • Ensuite, nous écrivons une fonction wrapper à appeler generate_exception dans une expression try ... catch.

Exemple

-module(helloworld). 
-compile(export_all). 

generate_exception(1) -> a; 
generate_exception(2) -> throw(a); 
generate_exception(3) -> exit(a); 
generate_exception(4) -> {'EXIT', a}; 
generate_exception(5) -> erlang:error(a). 

demo1() -> 
   [catcher(I) || I <- [1,2,3,4,5]]. 
catcher(N) -> 
   try generate_exception(N) of 
      Val -> {N, normal, Val} 
   catch 
      throw:X -> {N, caught, thrown, X}; 
      exit:X -> {N, caught, exited, X}; 
      error:X -> {N, caught, error, X} 
   end. 
      
demo2() -> 
   [{I, (catch generate_exception(I))} || I <- [1,2,3,4,5]]. 
demo3() -> 
   try generate_exception(5) 
   catch 
      error:X -> 
         {X, erlang:get_stacktrace()} 
   end. 
   
lookup(N) -> 
   case(N) of 
      1 -> {'EXIT', a}; 
      2 -> exit(a) 
   end.

Si nous exécutons le programme en tant que helloworld: demo (). , nous obtiendrons la sortie suivante -

Production

[{1,normal,a},
{2,caught,thrown,a},
{3,caught,exited,a},
{4,normal,{'EXIT',a}},
{5,caught,error,a}]