繁体   English   中英

是否有必要为每个 'handle_call' function 添加 try do...catch?

[英]Is it necessary to add try do ...catch for every 'handle_call' function?

erlang中,如果没有 try catch, handle_call中的错误 function 会导致 GenServer 崩溃。 当它崩溃时,由于大量的崩溃和重启日志,很难找到问题所在。

我的问题是为什么这么多的 handle_call 还没有try catch语句? 有什么考虑?

以下代码来自Nx项目stream.ex文件,仅供学习。

  @impl true
  def handle_call(:recv, from, {output, waiting, acc, fun}) do
    case :queue.out(output) do
      {:empty, output} ->
        {:noreply, {output, :queue.in(from, waiting), acc, fun}}

      {{:value, data}, output} ->
        {:reply, {:ok, data}, {output, waiting, acc, fun}}
    end
  end

  @impl true
  def handle_call(:done, _from, {output, waiting, acc, fun}) do
    if :queue.is_empty(output) do
      for from <- :queue.to_list(waiting) do
        GenServer.reply(from, :done)
      end

      {:stop, :normal, {:ok, acc}, {output, waiting, acc, fun}}
    else
      {:reply, :recv_pending, {output, waiting, acc, fun}}
    end
  end

在 Elixir 中,使用try并不常见,大多数时候您实际上是想让它崩溃,而不是阻止它。 处理崩溃是监督树的工作,而不是恢复崩溃过程。 这篇文章应该有所帮助。

我认为Joe Armstrong 的论文(2003 年)的这段摘录也很有趣,它解释了 Erlang 错误处理和“让它崩溃”背后的哲学:

  1. 进程是错误封装的单位 [...]
  2. 流程做他们应该做的事情或尽快失败
  3. 远程进程可以检测到失败和失败的原因
  4. 进程不共享 state,但通过消息传递进行通信

另外,我认为您在这里混淆了catchrescuecatch意味着获取由throw传递的值,而rescue可以从意外错误中恢复。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM