エラーハンドリング構文と言えばJavaScriptではtry~catch, Rubyではbegin~rescue, Pythonではtry~except があります。  
そう、多くの言語でエラーハンドリング構文は1つです。しかしElixirには2種類のエラーハンドリング構文があります(!?)。
 それはタイトルにもある通りtry~catchとtry~rescueです。  
 このエントリでは2種類のエラーハンドリング構文try~catchとtry~rescueにどんな違いがあるのか説明します。  
 Elixirでは前提としてexample/1というメソッドは{:ok, result}か{:error, reason}を返すように設計します。  
case example(foo) do
  {:ok, result} -> # do_something
  {:error, reason} -> # do_something
end戻り値としてエラーを返すのはGoに似ていますね。
 result だけを返すかエラーを発生させるメソッドはメソッド名の末尾に!を付けて定義します。  
result = example!(foo) example!/1がエラーを発生させた場合、エラーをキャッチしなければプログラムは終了します。  
 ではエラーをキャッチするにはtry~catchとtry~rescueのどちらを使えば良いでしょうか?  
そのためにはまずElixirにおける2つのエラー発生方法を知る必要があります。
 Elixirではエラーを発生させる方法としてthrow/1とraiseがあります。  
 throw/1は、ある値を投げ、キャッチするために使います。が、あまり使うことはないようです。  
実際には新しいElixirコードでこれらを使うのは非常にまれです
 throw/1で投げた値はtry~catchで捕捉することができます。  
try do
  throw(1)
catch
  x -> "Caught: #{x}"
end またtry~catchではexitも捕捉できます。  
 通常、明示的にエラーを発生させたいときはraise/1やraise/2を使います。  
raise "Oh no!"
raise ArgumentError, message: "the argument value is invalid" raiseで発生させたエラーや、その他のランタイムエラーはtry~rescueを使って捕捉することができます。  
try do
  do_something!(foo)
rescue
  e in ArgumentError -> IO.puts("the argument value is invalid")
  e -> IO.puts("error: " <> inspect(e))
end またRubyのensure, Pythonのfinallyに相当するafter句もあります。  
 このエントリではElixirのエラーハンドリング構文try~catchとtry~rescueの違いを説明しました。  
私はその違いを理解しないまま本番にコードを反映してしまって...というのをやったことがあります。
 外部ライブラリを使う際などは、中でthrow/1が使われているのか、raiseが使われているのか気を付けてください。  
参考文献
 
  
 
コメントを送る
コメントはブログオーナーのみ閲覧できます