Erlang中的錯誤處理
erlang中錯誤大體分為四種:
1. 編譯錯誤
2. 邏輯錯誤
3. 執行時錯誤
4. 使用者程式碼生成的錯誤
編譯錯誤,主要是編譯器檢測出的程式碼語法錯誤
邏輯錯誤,是指程式沒有完成預期的工作,屬於開發人員的問題
執行時錯誤,是指erlang執行時丟擲的錯誤,比如對非資料型別執行算術運算,erlang執行時會捕獲異常,並丟擲。在erlang中,這類 異常的型別為error
使用者自定義錯誤,是指通過exit/1或者throw/1生成
我們把執行時錯誤以及使用者丟擲的錯誤稱為異常(exception),他們具有三種類型:throw, error, exit。
error型異常,通過erlang:error/1, 2生成,也可以使用早期的erlang:fault/1, 2
throw型異常,通過throw/1生成
exit型異常,通過exit/1生成
在erlang中,程序內的異常可以通過try, catch來進行捕獲處理。
推薦使用try,其為新新增的語法。程序間的異常可以通過監督樹(supervisor tree),監控程序(monitor)來實現。
badarg 引數錯誤,引數格式或型別錯誤
badarith 算術表示式錯誤,算術表示式中含有錯誤的引數
{badmatch,V} 模式匹配錯誤,V指具體的發生匹配錯誤的數值
function_clause 函式子句錯誤,沒有找到匹配的函式子句
{case_clause,V} case 匹配錯誤,沒有找到匹配的case pattern
if_clause if 子句錯誤,沒有找到為ture的if子句
{try_clause,V} try匹配錯誤,執行try時,沒有找到匹配的pattern
undef 函式未定義錯誤
{badfun,F} 函式錯誤
{badarity,F} 函式引數個數錯誤
timeout_value 超時引數錯誤,在receive.. after語法中,after對應的超時資料錯誤(應為不小於0的integer或infinity
noproc Process 錯誤,Process不存在
{nocatch,V} throw未被catch
system_limit 系統限制錯誤,某些效能或資料達到系統極限
try 語法
Erlang 程式碼- try Exprs [of
- Pattern1 [when GuardSeq1] ->
- Body1;
- …;
- PatternN [when GuardSeqN] ->
- BodyN
- catch
- [Class1:]ExceptionPattern1 [when ExceptionGuardSeq1] ->
- ExceptionBody1;
- …;
- [ClassN:]ExceptionPatternN [when ExceptionGuardSeqN] ->
- ExceptionBodyN
- end
12345678910111213 | tryExprs[ofPattern1[whenGuardSeq1]->Body1;...;PatternN[whenGuardSeqN]->BodyNcatch[Class1:]ExceptionPattern1[whenExceptionGuardSeq1]->ExceptionBody1;...;[ClassN:]ExceptionPatternN[whenExceptionGuardSeqN]->ExceptionBodyNend |
如果try Exprs後沒有of部分,則預設為Exprs的返回值。
如果在of部分或者catch部分,發生了異常,那麼異常將不被處理,直接丟擲。
下面的程式碼可以讓你充分的學習,理解try語法。
test_try.erl 下載程式碼
- -module(test_try).
- -compile([export_all]).
- -author(‘cheng [email protected]’).
- %% @spec test(F1, F2) -> Result
- %% @doc evaluate the F , use the try to catch all kinds of error
- %% F1 the Expression to be catch exception
- %% F2 the Expression evaluate in the catch section
- test(F1, F2) when (is_function(F1, 0) andalso is_function(F2, 0)) ->
- try F1()
- catch
- throw:X ->
- {{caught, throw, X}, F2()};
- exit:X ->
- {{caught, exit, X}, F2()};
- error:X ->
- {{caught, error, X}, F2()}
- after
- io:format("always evaluate the after body~n")
- end.
12345678910111213141516171819202122232425 | -module(test_try).-compile([export_all]).-author('cheng [email protected]').%%@spectest(F1,F2)->Result%%@docevaluatetheF,usethetrytocatchallkindsoferror%%F1theExpressiontobecatchexception%%F2theExpressionevaluateinthecatchsectiontest(F1,F2)when(is_function(F1,0)andalsois_function(F2,0))->tryF1()catchthrow:X->{{caught,throw,X},F2()};exit:X->{{caught,exit,X},F2()};error:X->{{caught,error,X},F2()}afterio:format("alwaysevaluatetheafterbody~n")end. |
執行:
Erlang 程式碼- 21> c(test_try).
- {ok,test_try}
- 22> test_try:test(fun() -> throw(hello) end, fun() -> ok end).
- always evaluate the after body
- {{caught,throw,hello},ok}
- 23> test_try:test(fun() -> exit(hello) end, fun() -> ok end).
- always evaluate the after body
- {{caught,exit,hello},ok}
- 24> test_try:test(fun() -> erlang:error(hello) end, fun() -> ok end).
- always evaluate the after body
- {{caught,error,hello},ok}
- 25> test_try:test(fun() -> erlang:error(hello) end, fun() -> throw(exception_in_catch) end).
- always evaluate the after body
- ** exception throw: exception_in_catch
- in function test_try:test/2