# 附錄D Erlang的錯誤處理
| 翻譯: | 趙衛國 |
|-----|-----|
本附錄提供了Erlang錯誤處理機制的細致總結。
### 匹配錯誤
當我們調用一個傳入錯誤參數的內建函數時,參數不匹配的函數時,匹配錯誤就會產生。
當遇到匹配錯誤時,系統的行為可以描述成以下幾種情形:
~~~
if(called a BIF with bad args)then
Error = badarg
elseif(cannot and a matching function)then
Error = badmatch
elseif(no matching case statement)then
Error = case_clause
...
if(within the scope of a “catch”)then
Value of “catch” = {'EXIT', Error}
else
broadcast(Error)
die
endif
~~~
其中“broadcast(Error)”可以描述為:
~~~
if(Process has Links)then
send {'EXIT', self(), Reason} signals to all linked
processes
endif
~~~
### 異常拋出
函數 throw(Reason) 的行為可以描述如下:
~~~
if(within the scope of a “catch”)then
Value of “catch” = Reason
else
broadcast(nocatch)
die
endif
~~~
### 退出信號
當接收到 {'EXIT',Pid,ExitReason} 信號時, Erlang 的行為可以描述成如下代碼:
~~~
if(ExitReason == kill)then
broadcast(killed) % note we change ExitReason
die
else
if(trapping exits)then
add {'EXIT', Pid, ExitReason}
to input mailbox
else
if(ExitReason == normal) then
continue
else
broadcast(ExitReason)
die
endif
endif
endif
~~~
如果進程表示符為 Sender 的進程運行一個簡單的函數 exit(Pid,Why) ,那么進程 Pid 就會收到一個代表進程 Sender**好像**死亡的消息 {'EXIT',Source,Why} 。
如果進程正常終止,把信號 {'EXIT',Source,normal} 發送到所有的鏈接進程.
函數 exit(Pid,kill) 產生一個無法銷毀的消息,它使的接收進程無條件死亡,把退出的原因改為 killed 并把退出的原因發送給所有的鏈接進程(如若不然,可能使服務器意想不到的崩潰).
### 未定義函數
當涉及到未定義函數或注冊進程,錯誤的最后一級就會發生。
如果在調用函數 Mod:Func(Arg0,...,ArgN) 但代碼中沒有這個函數時,就會觸發 error_handler:undefined_function(Mod,Func,[Arg0,...,ArgN]) 。
### error_logger
Erlang運行時系統生成的錯誤消息都轉化為下面這種形式:
~~~
{emulator,GroupLeader,Chars}
~~~
并把它發送給一個名為 error_logger 下的注冊進程。由于所有用戶代碼都可以在 error_logger 中運行,因此可以很容易的把錯誤信息發送到其他結點上處理。這兒的變量 GroupLeader 是錯誤產生進程的進程表示符。有了它, error_logger 就可以把錯誤返回給這個產生錯誤的進程,以便讓連接這個結點的終端打印出錯誤信息。