查看源码 错误和错误处理
术语
错误大致可以分为四种类型
编译时错误 - 当编译器无法编译程序时,例如语法错误。
逻辑错误 - 当程序没有按预期运行,但没有崩溃时。一个例子是点击图形用户界面中的按钮时没有任何反应。
运行时错误 - 当发生崩溃时。一个例子是将运算符应用于错误类型的参数。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}
。