处理错误元组列表时是否有标准做法?
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 中的异常被用作向父进程发送错误的机制,并且应该仅在应用程序中断时使用错误。”
在我的应用程序中,我想对值列表应用函数。
因为这些功能是通过网络 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 中的异常被用作向父进程发送错误的机制,并且应该仅在应用程序中断时使用错误。”