I have been trying to figure out how I can catch or rescue in the calling process B an error in another process A that also killed process A.
Here's my code:
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}"
In module B's handle_call function, I called module A's function and it has rescue block in case anything goes wrong with process :A. The error is raised but the rescue block doesn't get executed.
Have I missed basic understanding of how one process crash affects the other? Does try/catch or try/rescue work only if the error occurs in the same process? Do I have to monitor the other process and trap its exit?
I'll appreciate your help.
In Erlang ecosystem you can catch errors, exits and throws using try-catch only if exception is raised in process's code, but if a process exits with any reason except atom
normal, all linked process will receive exit signal, those processe which traped exit, will receive this signal as normal erlang message in form of{'EXIT', CrashedProcessPid, ReasonOfCrash}. And the other process which did not trap exit, will crash with reasonReasonOfCrashand other processes which are linked to these processes will receive signalz and so on.