Thanks for spelling it out. Yes it works.
defmodule A do
use GenServer
def start_link() do
GenServer.start_link(__MODULE__, nil, name: :a)
end
def apple() do
GenServer.call(:a, :apple)
end
def handle_call(:apple, _from, state) do
IO.puts "In apple handle_call, going to call banana"
try do
B.banana(5)
catch :exit, reason ->
IO.puts "caught :exit, reason is #{inspect reason}"
end
{:reply, :ok, state}
end
def handle_info(msg, state) do
IO.puts "Handle_info, msg received #{inspect msg}"
{:noreply, state}
end
end
defmodule B do
use GenServer
def start() do
GenServer.start(__MODULE__, nil, name: :b)
end
def banana(value) do
GenServer.call(:b, {:banana, value})
end
def handle_call({:banana, value}, _from, state) do
IO.puts "In banana handle_call, about to explode"
case value do
5 -> raise "Pigs are flying, crashing now"
_ -> ""
end
{:reply, :ok, state}
end
end
Interactive Elixir (1.3.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> B.start
{:ok, #PID<0.109.0>}
iex(2)> A.start_link
{:ok, #PID<0.111.0>}
iex(3)> A.apple
In apple handle_call, going to call banana
In banana handle_call, about to explode
caught :exit, reason is {{%RuntimeError{message: "Pigs are flying, crashing now"}, [{B, :handle_call, 3, [file: 'lib/propagate.ex', line: 50]}, {:gen_server, :try_handle_call, 4, [file: 'gen_server.erl', line: 615]}, {:gen_server, :handle_msg, 5, [file: 'gen_server.erl', line: 647]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}]}, {GenServer, :call, [:b, {:banana, 5}, 5000]}}
:ok
iex(4)>
12:03:47.149 [error] GenServer :b terminating
** (RuntimeError) Pigs are flying, crashing now
(propagate) lib/propagate.ex:50: B.handle_call/3
(stdlib) gen_server.erl:615: :gen_server.try_handle_call/4
(stdlib) gen_server.erl:647: :gen_server.handle_msg/5
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: {:banana, 5}
State: nil
nil
iex(5)> Process.whereis(:a)
#PID<0.111.0>
iex(6)> Process.whereis(:b)
nil