- Erlang 教程
- Erlang - 首頁
- Erlang - 概述
- Erlang - 環境
- Erlang - 基本語法
- Erlang - Shell
- Erlang - 資料型別
- Erlang - 變數
- Erlang - 運算子
- Erlang - 迴圈
- Erlang - 決策
- Erlang - 函式
- Erlang - 模組
- Erlang - 遞迴
- Erlang - 數字
- Erlang - 字串
- Erlang - 列表
- Erlang - 檔案 I/O
- Erlang - 原子
- Erlang - 對映
- Erlang - 元組
- Erlang - 記錄
- Erlang - 異常
- Erlang - 宏
- Erlang - 標頭檔案
- Erlang - 預處理器
- Erlang - 模式匹配
- Erlang - 守護程序
- Erlang - BIFS
- Erlang - 二進位制
- Erlang - 函式
- Erlang - 程序
- Erlang - 郵件
- Erlang - 資料庫
- Erlang - 埠
- Erlang - 分散式程式設計
- Erlang - OTP
- Erlang - 併發
- Erlang - 效能
- Erlang - 驅動程式
- Erlang - Web 程式設計
- Erlang 有用資源
- Erlang - 快速指南
- Erlang - 有用資源
- Erlang - 討論
Erlang - 異常
異常處理在任何程式語言中都是必需的,用於處理執行時錯誤,以便維護應用程式的正常流程。異常通常會中斷應用程式的正常流程,這就是為什麼我們需要在應用程式中使用異常處理的原因。
通常,當 Erlang 中發生異常或錯誤時,將顯示以下訊息。
{"init terminating in do_boot", {undef,[{helloworld,start,[],[]},
{init,start_it,1,[]},{init,start_em,1,[]}]}}
崩潰轉儲將寫入 -
erl_crash.dump init terminating in do_boot ()
在 Erlang 中,有三種類型的異常 -
錯誤 - 呼叫 erlang:error(Reason) 將終止當前程序中的執行,並在您捕獲它時包含最後呼叫的函式及其引數的堆疊跟蹤。這些是導致上面執行時錯誤的異常型別。
退出 - 有兩種型別的退出:'內部'退出和'外部'退出。內部退出是透過呼叫函式 exit/1 觸發的,並使當前程序停止執行。外部退出使用 exit/2 呼叫,並且與 Erlang 併發方面的多個程序有關。
丟擲 - 丟擲是一類異常,用於程式設計師可以預期處理的情況。與退出和錯誤相比,它們並沒有真正帶有任何“崩潰該程序!”的意圖,而是控制流程。當您在預期程式設計師處理丟擲時使用它們時,通常最好使用它們記錄模組中的用法。
try ... catch 是一種評估表示式的 方法,同時允許您處理成功的情況以及遇到的錯誤。
try catch 表示式的通用語法如下。
語法
try Expression of SuccessfulPattern1 [Guards] -> Expression1; SuccessfulPattern2 [Guards] -> Expression2 catch TypeOfError:ExceptionPattern1 -> Expression3; TypeOfError:ExceptionPattern2 -> Expression4 end
try 和 of 之間的表示式被稱為受保護的。這意味著在該呼叫中發生的任何型別的異常都將被捕獲。try ... of 和 catch 之間的模式和表示式與 case ... of 的行為完全相同。
最後,是 catch 部分 - 在這裡,您可以將 TypeOfError 替換為 error、throw 或 exit,分別對應我們本章中看到的每種型別。如果未提供型別,則假定為 throw。
以下是 Erlang 中的一些錯誤和錯誤原因 -
| 錯誤 | 錯誤型別 |
|---|---|
| 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 有問題 |
| {badarity,F} | 函式應用於錯誤數量的引數。F 描述了函式和引數。 |
| timeout_value | receive..after 表示式中的超時值計算結果不是整數或無限大。 |
| noproc | 嘗試連結到不存在的程序。 |
下面是一個關於如何使用這些異常以及如何執行操作的示例。
第一個函式生成所有可能的異常型別。
然後我們編寫一個包裝器函式,在 try...catch 表示式中呼叫 generate_exception。
示例
-module(helloworld).
-compile(export_all).
generate_exception(1) -> a;
generate_exception(2) -> throw(a);
generate_exception(3) -> exit(a);
generate_exception(4) -> {'EXIT', a};
generate_exception(5) -> erlang:error(a).
demo1() ->
[catcher(I) || I <- [1,2,3,4,5]].
catcher(N) ->
try generate_exception(N) of
Val -> {N, normal, Val}
catch
throw:X -> {N, caught, thrown, X};
exit:X -> {N, caught, exited, X};
error:X -> {N, caught, error, X}
end.
demo2() ->
[{I, (catch generate_exception(I))} || I <- [1,2,3,4,5]].
demo3() ->
try generate_exception(5)
catch
error:X ->
{X, erlang:get_stacktrace()}
end.
lookup(N) ->
case(N) of
1 -> {'EXIT', a};
2 -> exit(a)
end.
如果我們像 helloworld:demo() 那樣執行程式,我們將得到以下輸出 -
輸出
[{1,normal,a},
{2,caught,thrown,a},
{3,caught,exited,a},
{4,normal,{'EXIT',a}},
{5,caught,error,a}]