English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

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では、3例外の種類-

  • Error−呼び出しは現在のプロセスの実行を終了し、最後の関数及其引数までのスタックトレースを含みます。これらは上述のランタイムエラーを引き起こす例外です。erlang:error(Reason)

  • Exists −には、内部退出と外部退出の二種類があります。内部退出は、関数 exit/1をトリガーし、現在のプロセスの実行を停止させます。外部出口は exit/2が呼び出され、Erlangの並行処理の側面における複数のプロセスに関連しています。

  • Throw −throwはプログラマーが処理できる一種の例外です。例外と比較して、彼らは「クラッシュプロセス!」を引き起こすものではありません。彼らの背後の意図は、流量を制御することです。プログラマーが例外を投げることを期待している場合、通常、その使用を記録するのが最善です。

try...catchは計算表現の方法であり、成功例と遭遇するエラーを同時に処理できます。

try-catch表現の一般的な文法は以下の通りです。

文法

試行 表現 
成功パターン1 [警備員] -> 
Expression1; 
成功パターン2 [警備員] -> 
Expression2 
catch TypeOfError:ExceptionPattern1 -> 
Expression3; 
TypeOfError:ExceptionPattern2 -> 
Expression4 
end

tryとofの間の表現は保護されたと呼ばれます。これは、その呼び出しで発生するすべてのタイプの例外がキャッチされることを意味します。try...とcatchの間のパターンと表現はcase...の動作と完全に同じです。

最後に、catch部分——ここでは、本章で見たすべてのタイプに対して、error、throw、またはexitでTypeOfErrorを置き換えます。タイプが提供されていない場合、自動的に投げられます。

Errorエラータイプ
badarg

パラメータのデータ型が間違っているか、形式が正しくありません。

badarith

算術表現のエラーパラメータ。

{badmatch,V}

表現の評価が失敗しました。値Vが一致しません。

function_clause関数呼び出しを評価する際に、一致する関数子句を見つけることができませんでした。
{case_clause,V}

case文を計算する際に、一致する枝を見つけることができませんでした。値Vが一致しません。

if_clauseif文を評価する際に、真の枝を見つけることができませんでした。
{try_clause,V}

try文の節を計算する際に、一致する枝を見つけることができませんでした。値Vが一致しません。

undef関数呼び出しを評価する際に、その関数を見つけることができませんでした。
{badfun,F}楽しいFが問題を起こしました
{badarit,F}

エラーナンバーに適用される楽しみが一つです。Fはその楽しみと議論を表します。

timeout_valuereceive..after文のタイムアウト値は、整数や無限大以外の値として計算されます。
noproc存在しないプロセスにリンクしようと試みます。

以下に、これらの例外を使用する方法と、その処理の例を示します。

  • 最初の関数はすべての可能な例外の型を生成します。

  • それでは、generate_exceptionをtry…catch文で呼び出す包装器関数を書きます。

オンラインサンプル

-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}]