2010-01-29 4 views
2

Ceci est le message d'exception lancé par Gen_server lorsqu'il n'est pas démarré.Comment intercepter Message d'Exception à Erlang?

([email protected])32> R11 = system_warning:self_test("SysWarn"). 
** exception exit: {noproc, 
        {gen_server,call, 
        [system_warning_sup, 
         {start_child, 
         {system_warning_SysWarn, 
         {system_warning,start_link,[{system_warning_SysWarn}]}, 
         permanent,10,worker, 
         [system_warning]}}, 
         infinity]}} 
    in function gen_server:call/3 
    in call from system_warning_sup:'-start_child/1-lc$^0/1-0-'/1 
    in call from system_warning:self_test/1 
([email protected])33> R11. 
* 1: variable 'R11' is unbound 

Maintenant, ce que je veux faire est d'attraper ce message d'exception & mis dans la variable R11 (ci-dessus montre non liée). Je veux le faire parce que si gen_sever n'est pas démarré, je veux commencer après avoir reçu ce message. J'ai aussi essayé d'utiliser handle_info mais je n'ai pas réussi à intercepter l'exception ou je ne suis pas capable de l'implémenter correctement. Quelqu'un peut-il m'aider s'il vous plaît avec ce problème en fournissant du code par exemple.

+1

Trouvé une question liée à ma question. http://stackoverflow.com/questions/1335758/how-can-i-write-an-exception-stack-trace-in-erlang-after-catching-it – iankits

Répondre

6

Les deux réponses @ W55tKQbuRu28Q4xv et @Zed sont corrects mais un peu laconique. :-)

Il existe deux façons d'intercepter une erreur localement: catch et try. Les deux capturent également les retours non locaux générés par throw.

catch est l'ancien et le plus simple des deux et a la syntaxe catch Expr. Si une erreur se produit dans l'expression en cours d'évaluation, catch renvoie {'EXIT',ErrorValue}, sinon elle renvoie simplement la valeur de l'expression. Un problème avec cela est qu'il n'y a aucun moyen de voir comment la valeur de retour d'erreur a été générée afin qu'il puisse facilement être falsifié dans l'expression. De la même manière, vous ne pouvez pas voir si la valeur de retour provient d'un throw. N.B. c'est pas un bug mais une caractéristique. En outre, il s'agit d'un opérateur de préfixe avec une priorité faible, donc vous l'utiliseriez normalement comme:

R11 = (catch system_warning:self_test (....)) 

pour éviter toute confusion. C'était une erreur, il aurait dû être catch ... end.

throw est plus complexe et vous permet un meilleur contrôle sur ce qu'il faut attraper et comment gérer à la fois les retours normaux et les retours d'erreurs/non-locaux. Voir le manuel pour une description complète. L'exemple de @ Zed montre le cas le plus simple qui capte tout.

+0

Merci l'homme pour clarifier les choses ... c'était vraiment très utile. :) – iankits

+0

Doit avoir ramassé cela de Java, mais je n'ai jamais aimé l'ancienne syntaxe de capture ... exactement à cause de la "fonctionnalité" que vous mentionnez :) – Zed

0

Essayez d'utiliser 'attraper': R11 = prise system_warning: self_test (....)

+0

(zerg @ casper) 1> affaire prise drmaa: début() de (zerg @ casper) 1> E -> io: format ("~ p ~ n", [E]) fin. { 'EXIT', {FNUD, [{drmaa, commencer, []}, {erl_eval, do_apply, 5}, {erl_eval, expr, 5}, {erl_eval, expr, 5}, {shell, exprs, 6}, {shell, eval_exprs, 6}, {shell, eval_loop, 3}]}} ok (zerg @ casper) 2> – W55tKQbuRu28Q4xv

+0

Merci l'homme ... et désolé ... je n'étais pas au courant de beaucoup de choses à propos de catch chose qu'il peut aussi être écrit comme ça et j'ai essayé et ça n'a pas marché. :( – iankits

+0

paix bro! :) ma réponse n'était pas absolue correcte aussi. – W55tKQbuRu28Q4xv

5
> try           
> R11 = system_warning:self_test("SysWarn") 
> catch          
> Ex:Type -> {Ex,Type,erlang:get_stacktrace()}      
> end. 
Questions connexes