Erlang-exceptions

提供:Dev Guides
移動先:案内検索

アーラン-例外

アプリケーションの通常のフローを維持できるように、ランタイムエラーを処理するには、プログラミング言語で例外処理が必要です。 例外は通常、アプリケーションの通常のフローを中断します。これが、アプリケーションで例外処理を使用する必要がある理由です。

通常、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 ()

アーランでは、例外の3種類があります-

  • エラー-* erlang:error(Reason)*を呼び出すと、現在のプロセスで実行が終了し、キャッチしたときに引数で呼び出された最後の関数のスタックトレースが含まれます。 これらは、上記のランタイムエラーを引き起こす種類の例外です。
  • 存在-「内部」出口と「外部」出口の2種類の出口があります。 内部出口は、関数 exit/1 を呼び出すことによってトリガーされ、現在のプロセスの実行を停止します。 外部出口は exit/2 で呼び出され、Erlangの並行処理の側面で複数のプロセスを処理する必要があります。
  • Throw -スローは、プログラマが処理することが期待される場合に使用される例外のクラスです。 終了とエラーと比較して、「クラッシュプロセス」は実際には発生しません。それらの背後にある意図ではなく、フローを制御します。 プログラマがスローを処理することを期待しながらスローを使用する場合、通常はスローを使用するモジュール内でスローを使用することを文書化することをお勧めします。
  • 試してみてください…​ 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*.

最後に、キャッチ部分–ここでは、この章で見たそれぞれの型について、 TypeOfError をerror、throw、またはexitに置き換えることができます。 タイプが指定されていない場合、スローが想定されます。

以下は、Erlangのエラーとエラーの理由の一部です-

Error Type of Error
badarg Bad argument. The argument is of wrong data type, or is otherwise badly formed.
badarith Bad argument in an arithmetic expression.
\{badmatch,V} Evaluation of a match expression failed. The value V did not match.
function_clause No matching function clause is found when evaluating a function call.
\{case_clause,V} No matching branch is found when evaluating a case expression. The value V did not match.
if_clause No true branch is found when evaluating an if expression.
\{try_clause,V} No matching branch is found when evaluating the of-section of a try expression. The value V did not match.
undef The function cannot be found when evaluating a function call..
\{badfun,F} Something is wrong with a fun F
\{badarity,F} A fun is applied to the wrong number of arguments. F describes the fun and the arguments.
timeout_value The timeout value in a receive..after expression is evaluated to something else than an integer or infinity.
noproc Trying to link to a non-existing process.

以下は、これらの例外がどのように使用され、どのように実行されるかの例です。

  • 最初の関数は、考えられるすべてのタイプの例外を生成します。
  • 次に、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}]