处理错误元组列表时是否有标准做法?

Is there a standart practice when dealing with a list of error tuples?

在我的应用程序中,我想对值列表应用函数。

因为这些功能是通过网络 API 或数据库运行的,所以我必须检查错误。一个是 return 一个 {:ok, result}{:error, reason} 的元组,这将导致所述元组的列表。

我可以使用如下函数检查此列表。然而,这看起来很笨拙,我想知道是否有更优雅的解决方案。也许使用例外?

def check_errors(lst) do
    if Enum.any?(lst, fn {s, _} -> s == :error end) do
        errors = Enum.filter(lst, fn {s, b} -> s == :error end)
                    |> Enum.map(fn {s, b} -> b end)
        IO.puts("Found Errors: ")
        IO.inspect(errors)
        System.halt(0)
    else
        lst
    end
end

有很多不同的方式,但在描述的场景中,Enum.split_with/2 是你的朋友。

[{:ok, 1}, {:error, 2}, {:ok, 3}]
|> Enum.split_with(fn {:error, _} -> true; _ -> false end)
|> case do
  {[], oks} ->
     oks
  {errors, _} ->
     errors
     |> Enum.map(&elem(&1, 1))
     |> IO.inspect(label: "Found errors")
end

此外,瑞士刀 Enum.reduce/3 可以像其他所有需要折叠列表的情况一样使用。

[{:ok, 1}, {:error, 2}, {:ok, 3}]
|> Enum.reverse() # needed to prepend below
                  # preserving the original order
|> Enum.reduce(%{errors: [], oks: []}, fn
  {:error, error}, acc ->
    %{acc | errors: [error | acc.errors]}
  {:ok, ok}, acc ->
    %{acc | oks: [ok | acc.oks]}
end) 
#⇒ %{errors: [2], oks: [1, 3]}

正如@Daniel 在评论中所说的完全正确,“elixir 中的异常被用作向父进程发送错误的机制,并且应该仅在应用程序中断时使用错误。”