Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Erlang 如何捕获或救援称为过程';调用Elixir中的进程时发生崩溃错误_Erlang_Elixir_Otp - Fatal编程技术网

Erlang 如何捕获或救援称为过程';调用Elixir中的进程时发生崩溃错误

Erlang 如何捕获或救援称为过程';调用Elixir中的进程时发生崩溃错误,erlang,elixir,otp,Erlang,Elixir,Otp,我一直在试图找出如何在调用进程B时捕获或挽救另一个进程A中的错误,该错误也导致进程A死亡 这是我的密码: defmodule A do def start_link do GenServer.start_link(__MODULE__, :ok, name: :A) end def fun(fun_loving_person) do GenServer.call(fun_loving_person, :have_fun) end def init(:ok)

我一直在试图找出如何在调用进程B时捕获或挽救另一个进程A中的错误,该错误也导致进程A死亡

这是我的密码:

defmodule A do
  def start_link do
    GenServer.start_link(__MODULE__, :ok, name: :A)
  end

  def fun(fun_loving_person) do
    GenServer.call(fun_loving_person, :have_fun)
  end

  def init(:ok) do
    {:ok, %{}}
  end

  def handle_call(:have_fun, _from, state) do
    raise "TooMuchFun"
    {:reply, :ok, state}
  end
end

defmodule B do
  def start_link do
    GenServer.start_link(__MODULE__, :ok, name: :B)
  end

  def spread_fun(fun_seeker) do
    GenServer.call(:B, {:spread_fun, fun_seeker})
  end

  def init(:ok) do
    {:ok, %{}}
  end

  def handle_call({:spread_fun, fun_seeker}, _from, state) do
    result = A.fun(fun_seeker)
    {:reply, result, state}
  rescue
    RuntimeError -> IO.puts "Too much fun rescued"
    {:reply, :error, state}
  end
end

{:ok, a} = A.start_link
{:ok, _b} = B.start_link
result = B.spread_fun(a)
IO.puts "#{inspect result}"
在模块B的
handle\u call
函数中,我调用了模块A的函数,它有
rescue
块,以防进程
:A
出现任何错误。出现错误,但未执行
rescue

我是否错过了一个进程崩溃如何影响另一个进程的基本理解?try/catch或try/rescue是否仅在同一过程中发生错误时才起作用?我是否必须监视另一个进程并捕获其出口


非常感谢您的帮助。

在Erlang生态系统中,只有在进程代码中引发异常时,您才可以使用try catch捕获错误、退出和抛出,但如果进程以除atom
normal
以外的任何原因退出,所有链接进程都将收到退出信号,即跟踪退出的进程,将以
{'EXIT',CrashedProcessPid,ReasonOfCrash}
的形式作为正常erlang消息接收此信号。另一个没有陷阱退出的进程将崩溃,原因是
ReasonOfCrash
,链接到这些进程的其他进程将接收信号z,依此类推。

您可以通过让另一个进程监视此进程来完成您想要的任务。签出
流程。监控
的文档:

基本上,监控过程需要处理崩溃时生成的停机消息的信息:

handle_info({:DOWN, ref, :process, object, reason}, state) do
  # do something interesting here ...
end

请记住,您需要找出执行此操作和模式匹配的原因。

谢谢。所以,如果我理解你的意思,投掷/举起错误和捕捉/拯救错误必须在同一个过程中发生?谢谢。我B监控A并执行
handle\u info
for:DOWN消息。但是,B没有收到:DOWN消息。我还在调查。