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

发布于 2024-08-19 13:31:50 字数 1115 浏览 3 评论 0原文

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

([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

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

This is the Exception message thrown by Gen_server when its not started.

([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

Now, What I want to do is to catch this exception message & put into variable R11 (showed above as unbound). I want to do so because if gen_sever is not started then I want to start after getting this message. I also tried using handle_info but not able to trap the exception or may be not able to implement it correctly. Can any body please help me with this problem providing some code for example.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦忆晨望 2024-08-26 13:31:50

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

有两种方法可以在本地捕获错误:catchtry。两者还将捕获由 throw 生成的非本地返回。

catch 是两者中较旧且更简单的,其语法为 catch Expr。如果正在计算的表达式中发生错误,则 catch 返回 {'EXIT',ErrorValue},否则仅返回表达式的值。它的一个问题是无法查看错误返回值是如何生成的,因此很容易在表达式中伪造它。同样,您无法查看返回值是否来自 throw。请注意,这不是错误,而是一项功能。而且它是一个优先级较低的前缀运算符,因此您通常会像这样使用它:

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

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

throw 更复杂,允许您更好地控制要捕获的内容以及如何处理正常返回和错误/非本地返回。请参阅手册以获取完整说明。 @Zed 的示例显示了捕获所有内容的最简单情况。

Both the answers from @W55tKQbuRu28Q4xv and @Zed are correct but a little terse. :-)

There are two ways to locally catch an error: catchand try. Both will also catch non-local returns generated by throw.

catch is the older and simpler of the two and has the syntax catch Expr. If an error occurs in the expression being evaluated then catch returns {'EXIT',ErrorValue}, otherwise it just returns the value of the expression. One problem with it is that there is no way to see how the error return value has been generated so it can easily be faked in the expression. In the same way you can't see if the return value comes from a throw. N.B. this is not a bug but a feature. Also it is a prefix operator with a low priority so you would normally use it like:

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

to avoid confusion. This was a mistake, it should have been catch ... end.

throw is more complex and allows you much greater control over over what to catch and how to handle both the normal returns and error/non-local returns. See the manual for a full description. @Zed's example shows the simplest case which catches everything.

五里雾 2024-08-26 13:31:50
> try                                        
>   R11 = system_warning:self_test("SysWarn")
> catch                                      
>   Ex:Type -> {Ex,Type,erlang:get_stacktrace()}                       
> end.
> try                                        
>   R11 = system_warning:self_test("SysWarn")
> catch                                      
>   Ex:Type -> {Ex,Type,erlang:get_stacktrace()}                       
> end.
陌路黄昏 2024-08-26 13:31:50

尝试使用“catch”:
R11 = 捕捉系统警告:自我测试(....)

Try to use 'catch':
R11 = catch system_warning:self_test (....)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文