1. 程式人生 > >Erlang中的錯誤處理

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 程式碼 
  1. try Exprs [of  
  2.     Pattern1 [when GuardSeq1] ->  
  3.         Body1;  
  4.     …;  
  5.     PatternN [when GuardSeqN] ->  
  6.         BodyN  
  7. catch  
  8.     [Class1:]ExceptionPattern1 [when ExceptionGuardSeq1] ->  
  9.         ExceptionBody1;  
  10.     …;  
  11.     [ClassN:]ExceptionPatternN [when ExceptionGuardSeqN] ->  
  12.         ExceptionBodyN  
  13. 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 下載程式碼

Erlang 程式碼 
  1. -module(test_try).  
  2. -compile([export_all]).  
  3. -author(‘cheng [email protected]’).  
  4. %% @spec test(F1, F2) -> Result  
  5. %% @doc evaluate the F , use the try to catch all kinds of error  
  6. %%  F1 the Expression to be catch exception  
  7. %%  F2 the Expression evaluate in the catch section  
  8. test(F1, F2) when (is_function(F1, 0) andalso is_function(F2, 0)) ->  
  9.     try F1()  
  10.     catch  
  11.         throw:X ->  
  12.             {{caught, throw, X}, F2()};  
  13.         exit:X ->  
  14.             {{caught, exit, X}, F2()};  
  15.         error:X ->  
  16.             {{caught, error, X}, F2()}  
  17.     after  
  18.         io:format("always evaluate the after body~n")  
  19.     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 程式碼 
  1. 21> c(test_try).  
  2. {ok,test_try}  
  3. 22> test_try:test(fun() -> throw(hello) end, fun() -> ok end).  
  4. always evaluate the after body  
  5. {{caught,throw,hello},ok}  
  6. 23> test_try:test(fun() -> exit(hello) end, fun() -> ok end).  
  7. always evaluate the after body  
  8. {{caught,exit,hello},ok}  
  9. 24> test_try:test(fun() -> erlang:error(hello) end, fun() -> ok end).  
  10. always evaluate the after body  
  11. {{caught,error,hello},ok}  
  12. 25> test_try:test(fun() -> erlang:error(hello) end, fun() -> throw(exception_in_catch) end).  
  13. always evaluate the after body  
  14. ** exception throw: exception_in_catch  
  15. in function test_try:test/