如何区分Elixir的`with`宏中的错误?

And*_*nce 3 elixir

通常,我的代码使用with宏来确保在继续操作之前所有必需的数据都可用,但是我想拥有更多细粒度的错误来准确确定其失败原因。

使用文档中的示例:

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

我想知道错误元组中是否缺少widthheight

我的尝试是使用默认值:

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
Run Code Online (Sandbox Code Playgroud)

但这并不特别优雅。有没有更惯用的方式?

m3c*_*ers 5

您可以将with行包装在描述性元组上,并仍然在所需的返回值上断言,这将使您能够辨别/提供错误所在。

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
Run Code Online (Sandbox Code Playgroud)