Erlang - 异常
任何编程语言都需要异常处理来处理运行时错误,以便维持应用程序的正常流程。 异常通常会破坏应用程序的正常流程,这就是我们需要在应用程序中使用异常处理的原因。
通常,当Erlang发生异常或错误时,会显示以下消息。
{"init terminating in do_boot", {undef,[{helloworld,start,[],[]},
{init,start_it,1,[]},{init,start_em,1,[]}]}}
故障转储将被写入 −
erl_crash.dump init terminating in do_boot ()
在Erlang中,有3种类型的异常 −
Error − 调用 erlang:error(Reason) 将结束当前进程中的执行,并在捕获它时包含最后调用的函数及其参数的堆栈跟踪。 这些是引发上述运行时错误的异常类型。
Exists − 有两种Exists:"internal(内部)"和"external(外部)"Exists。 内部退出是通过调用函数exit/1触发的,使当前进程停止执行。 外部出口用 exit/2 调用,并且与 Erlang 并发方面的多个进程有关。
Throw − 抛出是一类异常,用于程序员可以处理的情况。 与退出和错误相比,它们实际上并没有带来任何"进程崩溃!" 他们背后有意图,但他们控制着流程。 当您使用 throws 并期望程序员处理它们时,通常最好在使用它们的模块中记录它们的使用情况。
try ... catch 是一种计算表达式的方法,同时让您处理成功的情况以及遇到的错误。
try catch 表达式的一般语法如下。
语法
try Expression of SuccessfulPattern1 [Guards] -> Expression1; SuccessfulPattern2 [Guards] -> Expression2 catch TypeOfError:ExceptionPattern1 -> Expression3; TypeOfError:ExceptionPattern2 -> Expression4 end
try 和 of 之间的表达式被认为是受保护的。 这意味着该调用中发生的任何类型的异常都将被捕获。 try ... of 和 catch 之间的模式和表达式与 case ... of 的行为方式完全相同。
最后,catch 部分 - 在这里,对于我们在本章中看到的每种类型,您可以将 TypeOfError 替换为错误、抛出或退出。 如果未提供类型,则假定抛出异常。
以下是Erlang中的一些错误以及错误原因 −
| 错误 | 错误类型 |
|---|---|
| badarg | 糟糕的论点。 参数的数据类型错误,或者格式错误。 |
| badarith | 算术表达式中的参数错误。 |
| {badmatch,V} | 匹配表达式的计算失败。 值 V 不匹配。 |
| function_clause | 评估函数调用时未找到匹配的函数子句。 |
| {case_clause,V} | 评估 case 表达式时未找到匹配的分支。 值 V 不匹配。 |
| if_clause | 计算 if 表达式时未找到真正的分支。 |
| {try_clause,V} | 在计算 try 表达式的 of 部分时未找到匹配的分支。 值 V 不匹配。 |
| undef | 评估函数调用时找不到该函数.. |
| {badfun,F} | 有趣的F出了点问题 |
| {badarity,F} | 将 fun 应用于错误数量的参数。 F描述了乐趣和争论。 |
| timeout_value | receive..after 表达式中的超时值被计算为整数或无穷大以外的值。 |
| noproc | 尝试链接到不存在的进程。 |
以下是如何使用这些异常以及如何完成操作的示例。
第一个函数生成所有可能的异常类型。
然后我们编写一个包装函数来在 try...catch 表达式中调用 generate_exception。
示例
-module(helloworld).
-compile(export_all).
generate_exception(1) -> a;
generate_exception(2) -> throw(a);
generate_exception(3) -> exit(a);
generate_exception(4) -> {'EXIT', a};
generate_exception(5) -> erlang:error(a).
demo1() ->
[catcher(I) || I <- [1,2,3,4,5]].
catcher(N) ->
try generate_exception(N) of
Val -> {N, normal, Val}
catch
throw:X -> {N, caught, thrown, X};
exit:X -> {N, caught, exited, X};
error:X -> {N, caught, error, X}
end.
demo2() ->
[{I, (catch generate_exception(I))} || I <- [1,2,3,4,5]].
demo3() ->
try generate_exception(5)
catch
error:X ->
{X, erlang:get_stacktrace()}
end.
lookup(N) ->
case(N) of
1 -> {'EXIT', a};
2 -> exit(a)
end.
如果我们将程序运行为 helloworld:demo()。 ,我们将得到以下输出−
输出
[{1,normal,a},
{2,caught,thrown,a},
{3,caught,exited,a},
{4,normal,{'EXIT',a}},
{5,caught,error,a}]

