ok and error tuples
| Return {:ok, value} | |
| Return {:error, reason} | |
| Handle with with | |
| Bang functions or raise |
Return {:ok, value}
Elixir functions signal success with a two element tuple tagged with the atom ok. Callers match on the tag instead of guessing from the value shape. Wrapping the result keeps success explicit even when the value itself could be anything.
defmodule Calc do
def divide(a, b) do
{:ok, a / b}
end
end
IO.inspect(Calc.divide(7, 2))
{:ok, 3.5}
Return {:error, reason}
Failure uses the same shape with the atom error and a reason term such as an atom. A dedicated clause matches the bad input first, so the main clause only sees valid data. Callers then branch on the tag instead of rescuing an exception.
defmodule Calc do
def divide(_a, 0) do
{:error, :zero_division}
end
def divide(a, b) do
{:ok, a / b}
end
end
IO.inspect(Calc.divide(7, 0))
{:error, :zero_division}
Handle with with
The with construct chains steps that each return ok tuples and stops at the first mismatch. Each generator matches its pattern, and the do body runs only when every step succeeds. The else branch receives the unmatched value, so one place handles all failure shapes.
with {:ok, data} <- File.read("notes.txt") do
IO.puts(data)
else
{:error, reason} -> IO.puts("missing: #{reason}")
end
When the file exists the body prints its text, otherwise the else branch prints the reason.
Bang functions or raise
Many File functions come in pairs: the plain form returns an ok or error tuple while the bang form ends with an exclamation mark. The bang form returns the value directly and raises when something goes wrong. Reach for it when failure should stop the process instead of branching.
data = File.read!("notes.txt")
IO.puts(data)
Next: Files and IO
Article author: Arthur Isaev