Erlang无法捕获的异常

时间:2014-05-06 16:11:56

标签: exception-handling erlang

我在Erlang中有以下代码,其中我正在修复一个不存在的模块。 在某些版本的Erlang / meck中,这会产生一个似乎无法捕获的异常。

任何人都知道Erlang中是否存在“无法捕获的异常”功能?

try
    meck:new(i_dont_exist),
    io:format("No exception in this version of Erlang ... :( "),
    no_problems
catch
    exit:_ -> exit;
    error:_ -> error;
    throw:_ -> throw;
    _:_ -> what_class_is_it
    after
        io.format("in the after~n")
end.

当我执行这段代码时,这就是我得到的(请注意,甚至没有“after”子句被执行所以它看起来更像是一个bug):

** exception exit: {undefined_module,i_dont_exist}
     in function  meck_proc:resolve_can_expect/3 (src/meck_proc.erl, line 402)
     in call from meck_proc:init/1 (src/meck_proc.erl, line 194)
     in call from gen_server:init_it/6 (gen_server.erl, line 304)
     in call from proc_lib:init_p_do_apply/3 (proc_lib.erl, line 227)

我也尝试使用“catch”表达式,结果相同:

> catch meck:new(i_dont_exist).
** exception exit: {undefined_module,i_dont_exist}
     in function  meck_proc:resolve_can_expect/3 (src/meck_proc.erl, line 402)
     in call from meck_proc:init/1 (src/meck_proc.erl, line 194)
     in call from gen_server:init_it/6 (gen_server.erl, line 304)
     in call from proc_lib:init_p_do_apply/3 (proc_lib.erl, line 227)

1 个答案:

答案 0 :(得分:4)

这里发生的事情是meck:new使用gen_server回调模块生成一个新进程(meck_proc进程),并且该进程退出时出现undefined_module错误。 (你可以通过将non_strict选项传递给meck:new来实现这一点。)这个新进程链接到调用进程,这意味着退出信号将被发送到调用进程,调用进程也将退出,但无法catch信号。

您可以通过退出调用进程陷阱来避免这种情况:

process_flag(trap_exit, true)

会将退出信号转换为可以receive的消息;有关详细信息,请参阅the manual。但是,作为一般规则,您应该避免捕获出口,因为它使错误处理更复杂(与默认的“崩溃,重启”相反)。