当前位置: 首页 > 文档资料 > Erlang 中文教程 >

异常( Exceptions)

优质
小牛编辑
127浏览
2023-12-01

任何编程语言都需要异常处理来处理运行时错误,以便可以保持应用程序的正常流程。 异常通常会破坏应用程序的正常流程,这就是我们需要在应用程序中使用异常处理的原因。

通常,当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 - 退出有两种:“内部”退出和“外部”退出。 通过调用函数exit/1触发内部退出,并使当前进程停止执行。 外部出口使用exit/2调用,并且与Erlang的并发方面中的多个进程有关。

  • Throw - 抛出是一类异常,用于程序员可以处理的情况。 与出口和错误相比,他们并没有真正承担任何“崩溃过程!” 他们背后的意图,而是他们控制流量。 当您在期望程序员处理它们的同时使用throws时,通常最好在使用它们的模块中记录它们的使用。

try ... catch是一种评估表达式的方法,同时让您处理成功的案例以及遇到的错误。

try catch表达式的一般语法如下。

语法 (Syntax)

<b>try</b> Expression of 
SuccessfulPattern1 [Guards] -> 
Expression1; 
SuccessfulPattern2 [Guards] -> 
Expression2 
<b>catch</b> 
TypeOfError:ExceptionPattern1 -> 
Expression3; 
TypeOfError:ExceptionPattern2 -> 
Expression4 
<b>end</b>

try and of之间的表达被认为是受到保护的。 这意味着将捕获该调用中发生的任何类型的异常。 try ... of and catch之间的模式和表达式的行为方式与case ... of完全相同。

最后,catch部分 - 在这里,您可以通过error,throw或exit替换TypeOfError ,对于我们在本章中看到的每个相应类型。 如果没有提供类型,则假定抛出。

以下是Erlang中的一些错误和错误原因 -

错误错误类型
badarg不好的论点。 参数是错误的数据类型,或者是否形成错误。
badarith算术表达式中的错误参数。
{badmatch,V}评估匹配表达式失败。 值V不匹配。
function_clause在评估函数调用时,找不到匹配的函数子句。
{case_clause,V}在评估案例表达式时,找不到匹配的分支。 值V不匹配。
if_clause在评估if表达式时,找不到真正的分支。
{try_clause,V}在评估try表达式的section部分时,找不到匹配的分支。 值V不匹配。
undef评估函数调用时找不到该函数。
{badfun,F}有趣的F有点不对劲
{badarity,F}乐趣适用于错误数量的参数。 F描述了乐趣和论点。
timeout_valuereceive..after表达式中的超时值被计算为除整数或无穷大之外的值。
noproc尝试链接到不存在的进程。

以下是如何使用这些异常以及如何完成任务的示例。

  • 第一个函数生成所有可能的异常类型。

  • 然后我们编写一个包装函数来在try ... catch表达式中调用generate_exception

例子 (Example)

-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()。 ,我们将获得以下输出 -

输出 (Output)

[{1,normal,a},
{2,caught,thrown,a},
{3,caught,exited,a},
{4,normal,{'EXIT',a}},
{5,caught,error,a}]