如何在Erlang中捕获异常消息?

ian*_*its 2 erlang exception-handling exception

这是Gen_server未启动时抛出的异常消息.

(ankit@127.0.0.1)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
(ankit@127.0.0.1)33> R11.
* 1: variable 'R11' is unbound
Run Code Online (Sandbox Code Playgroud)

现在,我想要做的是捕获此异常消息并放入变量R11(上面显示为未绑定).我想这样做,因为如果gen_sever没有启动,那么我想在收到此消息后开始.我也尝试使用handle_info但不能捕获异常或者可能无法正确实现它.任何人都可以帮我解决这个问题,例如提供一些代码.

rvi*_*ing 6

来自@ W55tKQbuRu28Q4xv和@Zed的答案都是正确的,但有点简洁.:-)

有两种方法可以在本地捕获错误:catchtry.两者都将捕获由此产生的非本地回报throw.

catch是两者中较旧和较简单的,并具有语法catch Expr.如果正在计算的表达式中发生错误,则catch返回{'EXIT',ErrorValue},否则它只返回表达式的值.它的一个问题是无法看到如何生成错误返回值,因此它很容易在表达式中伪造.以同样的方式,你无法看到返回值是否来自a throw.注意,这不是一个错误,而是一个功能.它也是一个优先级较低的前缀运算符,因此您通常会使用它:

R11 = (catch system_warning:self_test (....))
Run Code Online (Sandbox Code Playgroud)

避免混淆.这是一个错误,它应该是catch ... end.

throw更复杂,允许您更好地控制捕获的内容以及如何处理正常返回和错误/非本地返回.有关完整说明,请参阅手册.@ Zed的例子展示了捕获一切的最简单的案例.


Zed*_*Zed 5

> try                                        
>   R11 = system_warning:self_test("SysWarn")
> catch                                      
>   Ex:Type -> {Ex,Type,erlang:get_stacktrace()}                       
> end.
Run Code Online (Sandbox Code Playgroud)