3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Elixirの対話モードでtryとcatchおよびrescueの動作を確認してみた

Posted at

概要

Elixirの対話モードでtryとcatchおよびrescueの動作を確認してみました。以下のページを参考にしました。

対話モードで実行

以下のコマンドを実行しました。

$ iex
Erlang/OTP 24 [erts-12.2.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit]

Interactive Elixir (1.12.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> :atom + 1
** (ArithmeticError) bad argument in arithmetic expression: :atom + 1
    :erlang.+(:atom, 1)
iex(1)> raise "oops"
** (RuntimeError) oops

iex(1)> raise(ArgumentError, message: "invalid argument")
** (ArgumentError) invalid argument

iex(1)> defmodule MyError do
...(1)> defexception message: "default message"
...(1)> end
{:module, MyError,
 <<70, 79, 82, 49, 0, 0, 13, 88, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 1, 88,
   0, 0, 0, 34, 14, 69, 108, 105, 120, 105, 114, 46, 77, 121, 69, 114, 114, 111,
   114, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, :ok}
iex(2)> raise MyError
** (MyError) default message

iex(2)> raise MyError, message: "custom message"
** (MyError) custom message

iex(2)> try do
...(2)> raise MyError
...(2)> rescue
...(2)> err in MyError -> err
...(2)> end
%MyError{message: "default message"}
iex(3)> try do
...(3)> raise "oops"
...(3)> rescue
...(3)> err in RuntimeError -> err
...(3)> end
%RuntimeError{message: "oops"}
iex(4)> try do
...(4)> raise "oops"
...(4)> rescue
...(4)> RuntimeError -> "Error!"
...(4)> end
"Error!"
iex(5)> File.read "hello"
{:error, :enoent}
iex(6)> File.write "hello", "world"
:ok
iex(7)> File.read "hello"
{:ok, "world"}
iex(8)> defmodule Example do
...(8)> def read_file(file) do
...(8)> case File.read file do
...(8)> {:ok, body} -> IO.puts "Success: #{body}"
...(8)> {:error, reason} -> IO.puts "Error: #{reason}"
...(8)> end
...(8)> end
...(8)> end
{:module, Example,
 <<70, 79, 82, 49, 0, 0, 7, 8, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 228, 0,
   0, 0, 24, 14, 69, 108, 105, 120, 105, 114, 46, 69, 120, 97, 109, 112, 108,
   101, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:read_file, 1}}
iex(9)> Example.read_file("hello")
Success: world
:ok
iex(10)> Example.read_file("unknown")
Error: enoent
:ok
iex(11)> File.read! "unknown"
** (File.Error) could not read file "unknown": no such file or directory
    (elixir 1.12.2) lib/file.ex:355: File.read!/1
iex(11)> try do
...(11)> for x <- 0..10 do
...(11)> if x > 4, do: throw(x)
...(11)> IO.puts(x)
...(11)> end
...(11)> catch
...(11)> x -> "Caught: #{x}"
...(11)> end
0
1
2
3
4
"Caught: 5"
iex(12)> Enum.find(0..10, &(&1 >  4))
5
iex(13)> spawn_link fn -> exit("oh no") end
** (EXIT from #PID<0.106.0>) shell process exited with reason: "oh no"

Interactive Elixir (1.12.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> try do
...(1)> exit "oh no!"
...(1)> catch
...(1)> :exit, _ -> "exit blocked"
...(1)> end
"exit blocked"
iex(2)> try do
...(2)> raise "Oh no!"
...(2)> rescue
...(2)> err in RuntimeError -> IO.puts("An error occurred: " <> err.message)
...(2)> after
...(2)> IO.puts "The end!"
...(2)> end
An error occurred: Oh no!
The end!
:ok
iex(3)> defmodule Example do
...(3)> def handle_file(path, string) do
...(3)> {:ok, file} = File.open(path, [:utf8, :write])
...(3)> try do
...(3)> IO.write file, string
...(3)> raise "oops, something went wrong"
...(3)> after
...(3)> File.close(file)
...(3)> IO.puts "the file is closed"
...(3)> end
...(3)> end
...(3)> end
warning: redefining module Example (current version defined in memory)
  iex:3

{:module, Example,
 <<70, 79, 82, 49, 0, 0, 7, 20, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 228,
   0, 0, 0, 24, 14, 69, 108, 105, 120, 105, 114, 46, 69, 120, 97, 109, 112, 108,
   101, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:handle_file, 2}}
iex(4)> Example.handle_file("hello", "world")
the file is closed
** (RuntimeError) oops, something went wrong
    iex:8: Example.handle_file/2
iex(4)> defmodule RunAfter do
...(4)> def without_even_trying do
...(4)> raise "oops"
...(4)> after
...(4)> IO.puts "cleaning up!"
...(4)> end
...(4)> end
{:module, RunAfter,
 <<70, 79, 82, 49, 0, 0, 5, 248, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 205,
   0, 0, 0, 19, 15, 69, 108, 105, 120, 105, 114, 46, 82, 117, 110, 65, 102, 116,
   101, 114, 8, 95, 95, 105, 110, 102, 111, ...>>, {:without_even_trying, 0}}
iex(5)> RunAfter.without_even_trying
cleaning up!
** (RuntimeError) oops
    iex:6: RunAfter.without_even_trying/0
iex(5)> x = 2
2
iex(6)> try do
...(6)> 1 / x
...(6)> rescue
...(6)> ArithmeticError ->
...(6)> :infinity
...(6)> else
...(6)> y when y < 1 and y > -1 ->
...(6)> :small
...(6)> _ ->
...(6)> :large
...(6)> end
:small
iex(7)> what_happened = :outside
:outside
iex(8)> try do
...(8)> raise "fail"
...(8)> what_happened = :did_not_raise
...(8)> rescue
...(8)> _ -> what_happened = :rescued
...(8)> end
warning: variable "what_happened" is unused (there is a variable with the same name in the context, use the pin operator (^) to match on it or prefix this variable with underscore if it is not meant to be used)
  iex:10

warning: variable "what_happened" is unused (there is a variable with the same name in the context, use the pin operator (^) to match on it or prefix this variable with underscore if it is not meant to be used)
  iex:12

:rescued
iex(9)> what_happened
:outside
iex(10)> what_happened =
...(10)> try do
...(10)> raise "fail"
...(10)> :did_not_raise
...(10)> rescue
...(10)> _ -> :rescued
...(10)> end
:rescued
iex(11)> what_happened
:rescued
iex(12)> 

まとめ

何かの役に立てばと。

3
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?