查看源码 错误和错误处理
术语
错误大致可以分为四种类型
编译时错误 - 当编译器无法编译程序时,例如语法错误。
逻辑错误 - 当程序没有按预期运行,但没有崩溃时。一个例子是点击图形用户界面中的按钮时没有任何反应。
运行时错误 - 当发生崩溃时。一个例子是将运算符应用于错误类型的参数。Erlang 编程语言具有用于处理运行时错误的内置功能。运行时错误也可以通过调用
error(Reason)来模拟。运行时错误是error类的异常。生成的错误 - 当代码本身调用
exit/1或throw/1时。生成的错误是exit或throw类的异常。
当 Erlang 中发生异常时,执行有错误的表达式的进程会停止。这被称为失败,执行或评估失败,或者进程失败、终止或退出。请注意,进程可能由于失败以外的其他原因而终止/退出。
终止的进程会发出一个退出信号,其中包含描述进程为何终止的退出原因。通常,有关任何错误终止的一些信息会打印到终端。有关终止的更多详细信息,请参阅进程章节中的进程终止。
异常
异常是运行时错误或生成的错误,分为三种不同的类别,具有不同的来源。 try 表达式可以区分不同的类别,而 catch 表达式不能。try 和 catch 在 表达式中描述。
| 类别 | 来源 |
|---|---|
error | 运行时错误,例如 1+a,或进程调用了 error/1 |
exit | 进程调用了 exit/1 |
throw | 进程调用了 throw/1 |
表:异常类别。
以上所有异常也可以通过调用 erlang:raise/3 来生成。
异常由其类别、退出原因(请参阅退出原因)和堆栈跟踪(有助于查找异常的代码位置)组成。
堆栈跟踪可以从 try 表达式中绑定到任何异常类别的变量,或者作为 catch 捕获运行时错误时退出原因的一部分。示例
> {'EXIT',{test,Stacktrace}} = (catch error(test)), Stacktrace.
[{shell,apply_fun,3,[]},
{erl_eval,do_apply,6,[]},
...]
> try throw(test) catch Class:Reason:Stacktrace -> Stacktrace end.
[{shell,apply_fun,3,[]},
{erl_eval,do_apply,6,[]},
...]调用堆栈回溯(堆栈跟踪)
堆栈回溯 (stacktrace) 是一个列表,其中包含 {Module, Function, Arity, ExtraInfo} 和/或 {Fun, Arity, ExtraInfo} 元组。元组中的 Arity 字段可以是该函数调用的参数列表,而不是一个算术整数,具体取决于异常。
ExtraInfo 是一个(可能为空的)双元素元组列表,其中以任意顺序提供有关异常的附加信息。第一个元素是描述第二个元素中信息类型的原子。可能会出现以下项
error_info- 元组的第二个元素是一个映射,提供有关导致异常原因的附加信息。此信息可以通过调用error/3来创建,并由erl_error:format_exception/4使用。file- 元组的第二个元素是一个字符串(字符列表),表示函数源文件的文件名。line- 元组的第二个元素是发生异常或调用函数的源文件中的行号(整数 > 0)。
警告
开发人员应仅将堆栈跟踪条目用于调试目的。
虚拟机执行尾调用优化,这不会向堆栈跟踪添加新条目,并且还将堆栈跟踪限制为一定的深度。此外,编译器选项、优化和未来的更改可能会添加或删除堆栈跟踪条目,从而导致任何期望堆栈跟踪以特定顺序或包含特定项的代码失败。
此规则的唯一例外是具有原因
undef的error类,它保证将尝试的函数的Module、Function和Arity作为第一个堆栈跟踪条目。
在 Erlang 中处理运行时错误
进程内的错误处理
可以通过使用 try 或 catch 来防止运行时错误和其他异常导致进程终止。
进程之间的错误处理
进程可以监视其他进程并检测进程终止,请参阅进程。
退出原因
当发生运行时错误时,即 error 类的异常。退出原因是元组 {Reason,Stack},其中 Reason 是一个表示错误类型的术语
badarg- 错误的参数。参数的数据类型错误,或者格式错误。badarith- 算术表达式的参数不是数字,或者表达式不能计算为有限数。{badmatch,V}- 匹配表达式的求值失败。值V不匹配。function_clause- 在计算函数调用时,找不到匹配的函数子句。{case_clause,V}- 在计算case表达式时,找不到匹配的分支。值V不匹配。if_clause- 在计算if表达式时,找不到 true 分支。{try_clause,V}- 在计算try表达式的 of 部分时,找不到匹配的分支。值V不匹配。undef- 在计算函数调用时,找不到该函数。{badfun,F}- 预期F是一个 fun,但不是。{badarity,{Fun,Args}}- fun 应用于错误数量的参数。timeout_value-receive...after表达式中的超时值被计算为整数或infinity以外的值。noconnection- 由于无法建立节点之间的连接或连接已断开,因此与远程进程的链接或监视中断。{nocatch,V}- 尝试在catch外部评估throw。V是抛出的术语。system_limit- 已达到系统限制。有关系统限制的信息,请参阅效率指南中的系统限制。
Stack 是发生错误时正在计算的函数调用堆栈,以元组 {Module,Name,Arity,ExtraInfo} 的列表形式给出,最近的函数调用在前。在某些情况下,最近的函数调用元组可以是 {Module,Name,[Arg],ExtraInfo}。