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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With