Erlang中的运行时错误包括:badarg, badarith, badmatch, function_clause, case_clause, if_clause, undef, noproc, system_limit等。其中function_clause, case_clause, if_clause,badmatch是最常见的错误。
1. badarg
参数类型错误,传入参数和函数要求参数不匹配。如把atom作为参数传给erlang:integer_to_list/1
>erlang:integer_to_list(a).
** exception error: bad argument
in function integer_to_list/1
called as integer_to_list(a)
2. badarith
算实运算错误,如一个整数和atom相加
>10 + c.
** exception error: an error occurred when evaluating an arithmetic expression
in operator +/2
called as 10 + c
3. {badmatch,V}
模式匹配错误,最常见的例子是给一个变量赋不同的值。
>Val = 10. %% 给Val赋值
>10
>val = 11. %% Val已定义,模式匹配,抛出bad match异常
** exception error: no match of right hand side value 11
4. function_clause
函数已定义,但找不到匹配函数。如下面的函数test:add/2接收两个整数,并返回它们的和。如果传入小数,将找不到匹配的分支,抛出function_clause。
-module(test).
-export([add/2]).
add(A,B) when is_integer(A),is_integer(B) ->
A + B.
erl
1> test:add(10,1).
11
2> test:add(10,1.0).
** exception error: no function clause matching test:add(10,1.0) (test.erl, line 4)
5. {case_clause,V}
case表达式找不到匹配的分支。
> Val = 0,
> case Val of
1-> lt;
2 -> gt
end.
** exception error: no case clause matching 0
可以把“_”加到case的最后分支中,避免出现case_clause。
> Val = 0,
> case Val of
1-> lt;
2 -> gt;
_ -> skip
end.
6. if_clause
if 表达式要求最少有一个分支测试条件的结果为true,否则会引发错误。下面表达将会引发if_clause
Val = 10,
if Val < 0 ->
lt;
Val > 100 ->
gt
end.
** exception error: no true branch found when evaluating an if expression
在分支最后加入ture,可以避免if_clause
if Val < 0 ->
lt;
Val > 100 ->
gt;
true ->
skip
end.
7. undef
调用未定义的函数或模块,如:
test:sum().
** exception error: undefined function test:sum/0
8.noproc
进程不存在,如gen_server call一个不存在的进程:
Pid = pid(0,100,10).
gen_server:call(Pid,test).
** exception exit: {noproc,{gen_server,call,[<0.100.10>,test]}}
in function gen_server:call/2 (gen_server.erl, line 180)
9.system_limit
超出系统上限,如atom,ets,port,process等。下面为atom超出上限例子(注意:会使虚拟机退出):
erl +t 9000
1> lists:foreach(fun(_)-> N1= 10,
list_to_atom(<div
class="ngg-galleryoverview"
id="ngg-gallery-905189b50f0ecbc5b1dbe5a80540a6fc-1"><div class="slideshowlink"><a href='http://www.kongqingquan.com/archives/389/nggallery/slideshow/'>[Show as slideshow]a>div><div id="ngg-image-0" class="ngg-gallery-thumbnail-box" ><div class="ngg-gallery-thumbnail"><a href="http://www.kongqingquan.com/wp-content/gallery/test_record/20141110172834.png"
title=" "
data-image-id='1'
class="ngg-fancybox" rel="905189b50f0ecbc5b1dbe5a80540a6fc">"20141110172834"
alt="20141110172834"
src="http://www.kongqingquan.com/wp-content/gallery/test_record/thumbs/thumbs_20141110172834.png"
width="120"
height="90"
style="max-width:none;"
/>a>div>div><div class="ngg-clear">div>div>)
end,lists:seq(1,10000)).
Crash dump was written to: erl_crash.dump
no more index entries in atom_tab (max=9000)
异常处理
在开发中可使用try,catch捕获异常,同时也调用erlang:get_stacktrace(),获取栈信息,定位错误。
try:
%% 业务代码
Exprs
catch
Calss:Reason ->
%% 异常处理代码,
%% Calss为异常类型,Reason为异常原因
ok
end.
一个简单的例子:
-module(test).
-export([add/2]).
add(A,B) ->
try
A + B
catch
Class:Reason ->
io:format("Class:~p,Reason:~p~nstacktrace:~n~p",
[Class,Reason,erlang:get_stacktrace()]),
error
end.
Class:error,Reason:badarith
stacktrace:
[{test,add,2,[{file,"test.erl"},{line,6}]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,573}]},
{shell,exprs,7,[{file,"shell.erl"},{line,674}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,629}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,614}]}]errord
参考网址:
http://www.erlang.org/doc/reference_manual/errors.html
http://www.erlang.org/doc/reference_manual/expressions.html
本文转载自:http://www.kongqingquan.com/archives/389