3
3

More than 5 years have passed since last update.

Elixir Exception と try-rescue

Last updated at Posted at 2014-10-09

Elixir Exception と try-rescue

概要

Elixir の Exception と try-rescue について。

Exception

Exception の発生

文字列と数値を連結させてエラーを発生させてみます。

iex> "a" <> 1
** (ArgumentError) argument error

RuntimeError の発生

引数なしの raise マクロか、文字列引数のみの raise マクロで
RuntimeError を発生させることができます。

iex> raise
** (RuntimeError)
iex> raise "hogehoge"
** (RuntimeError) hogehoge

RuntimeError の発生

例外を引数にとる raise マクロか、
例外・文字列を引数にとるの raise マクロで
任意の Error を発生させることができます。

iex> raise ArgumentError
** (ArgumentError) argument error

iex> raise ArgumentError, "hogehoge"
** (ArgumentError) hogehoge

try rescue による例外の補足

try / rescue によって例外を補足出来ます。

try do
  some_logic
rescue
  # Error の返却
  e in ArgumentError -> e
  e in RuntimeError -> e
end
  • サンプル

乱数 1-100 を生成します。
基本は FizzBuzz のルールで返却値を決定しますが、
4の倍数なら RuntimeError
6の倍数なら ArgumentError
を返却します。
※倍数が大きい方が優先されます

30回繰り返して処理結果を確認します。

defmodule ExceptionSample do
  def random_raise do
    x = :random.uniform(100)
    strx = Integer.to_string(x)
    cond do
      rem(x, 15) == 0 ->
        "FizzBuzz" <> strx
      rem(x, 6) == 0 ->
        raise ArgumentError, strx
      rem(x, 5) == 0 ->
        "Buzz" <> strx
      rem(x, 4) == 0 ->
        raise strx
      rem(x, 3) == 0 ->
        "Fizz" <> strx
      true ->
        x
    end
  end

  def try_rescue do
    try do
      ExceptionSample.random_raise
    rescue
      e in ArgumentError -> e
      e in RuntimeError -> e
    end
  end

  def try_rescue_times(0) do
    # do nothing
  end

  def try_rescue_times(n) do
    IO.inspect ExceptionSample.try_rescue
    try_rescue_times(n - 1)
  end
end

ExceptionSample.try_rescue_times(30)
  • 出力1回目
"FizzBuzz45"
73
"Buzz95"
"Fizz51"
%RuntimeError{message: "32"}
"FizzBuzz60"
%RuntimeError{message: "92"}
67
%ArgumentError{message: "48"}
"FizzBuzz60"
"FizzBuzz15"
"Fizz21"
"Buzz70"
%RuntimeError{message: "16"}
%RuntimeError{message: "56"}
22
46
43
1
"Fizz57"
%ArgumentError{message: "48"}
41
31
%ArgumentError{message: "6"}
58
"Fizz99"
34
19
"Fizz21"
%RuntimeError{message: "4"}

注意

try - rescue はあくまでも例外のための仕組み。
処理フローの制御には利用しないこと。
処理フローの制御に利用したい場合は、
try - throw - catch を利用します。

参照

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3