Treeprit helps you run sequentially commands that may or may not fail during the process.
defmodule MyApp.Commands do
def run() do
Treeprit.new()
|> Treeprit.run(:first, fn _ -> {:ok, 1} end)
|> Treeprit.run(:second, fn _ -> {:ok, 2} end)
|> Treeprit.run(:third, &sum_first_and_second_value/1)
|> Treeprit.run(:fourth, fn _ -> raise "random error" end)
|> Treeprit.run(:fifth, &sum_first_and_fourth_value/1)
|> Treeprit.finally()
end
# This function will always pattern match because :first and :second runners has these return values
defp sum_first_and_second_value(%{first: first_value, second: second_value}) do
{:ok, first_value + second_value}
end
# This will not match because :first and :second is always returning {:ok, value}
defp sum_first_and_second_value(_not_ok) do
{:error, :first_or_second_not_available}
end
# This will not match because :fourth is throwing an error, so it will never pattern match with fourth atom inside the map
defp sum_first_and_fourth_value(%{first: first_value, fourth: fourth_value}) do
{:ok, first_value + fourth_value}
end
# This will match
defp sum_first_and_fourth_value(_not_ok) do
{:error, :first_or_fourth_not_available}
end
end
Then when you try to run this module on your shell, you will have the given results:
iex> MyApp.Commands.run()
%Treeprit{
results: %{
first: 1,
second: 2,
third: 3
},
errors: %{
fourth: %RuntimeError{message: "random error"},
fifth: :first_or_fourth_not_available
},
successful_operations: 3,
failed_operations: 2,
total_operations: 5
}
Add this project to your dependencies
def deps do
[
{:treeprit, "~> 0.1"}
]
end
A great example for this library usage is the common seed.exs
in Ecto projects. If you need a more structured way for running seeds, you can use this package and organize them with modules. Take a look at this example.