Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to differentiate errors in Elixir's `with` macro?

Tags:

elixir

Often I have code that uses the with macro to ensure all the required data is available before proceeding, but I want to have more fine-grained errors to determine precisely why it failed.

Using an example from the documentation:

with {:ok, width} <- Map.fetch(opts, :width),
     {:ok, height} <- Map.fetch(opts, :height) do
  {:ok, width * height}
else
  :error ->
    {:error, :wrong_data}
end

I would like to know whether the width or the height is missing in the error tuple.

My attempt is to use defaults:

with {:ok, width} <- Map.fetch(opts, :width, {:error, :missing_width}),
     {:ok, height} <- Map.fetch(opts, :height, {:error, :missing_height}) do
  {:ok, width * height}
else
  {:error, reason} = error -> error
end

But this doesn't feel particularly elegant. Is there a more idiomatic way?

like image 821
Andrew France Avatar asked Dec 28 '25 14:12

Andrew France


1 Answers

You can wrap your with lines on descriptive tuples and still assert on the return you want, this will then allow you to discern/provide feedback where the error was.

with(
     {_, {:ok, width}} <- {:width, Map.fetch(opts, :width)},
     {_, {:ok, height}} <- {:height, Map.fetch(opts, :height)}
  ) do

  {:ok, width * height}

else
  {what, :error} ->
    {:error, {what, :wrong_data}}
end
like image 53
m3characters Avatar answered Dec 31 '25 17:12

m3characters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!