Erlang运行时错误

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

你可能感兴趣的:(Erlang)