我在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)
答案 0 :(得分:4)
这里发生的事情是meck:new
使用gen_server
回调模块生成一个新进程(meck_proc
进程),并且该进程退出时出现undefined_module
错误。 (你可以通过将non_strict
选项传递给meck:new
来实现这一点。)这个新进程链接到调用进程,这意味着退出信号将被发送到调用进程,调用进程也将退出,但无法catch
信号。
您可以通过退出调用进程陷阱来避免这种情况:
process_flag(trap_exit, true)
会将退出信号转换为可以receive
的消息;有关详细信息,请参阅the manual。但是,作为一般规则,您应该避免捕获出口,因为它使错误处理更复杂(与默认的“崩溃,重启”相反)。