Hi,
I want to handle the following exit example ( String.to_integer(input)
is jus an example and can be replaced with raise
). This happen when I call My.GenServer.some_method(My.GenServer, "test")
. I will be grateful if someone has a suggestion for this.
10:26:42.321 [error] GenServer My.GenServer terminating
** (stop) exited in: Task.await(%Task{owner: #PID<0.124.0>, pid: #PID<0.128.0>, ref: #Reference<0.4181578440.4035444737.94083>}, 5000)
** (EXIT) an exception was raised:
** (ArgumentError) argument error
:erlang.binary_to_integer("test")
Here’s the code:
defmodule My.Application do
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
worker(My.GenServer, []),
supervisor(Task.Supervisor, [[name: My.Task.Supervisor, restart: :transient]]),
]
opts = [strategy: :one_for_one, name: Test.Supervisor]
Supervisor.start_link(children, opts)
end
end
defmodule My.GenServer do
def start_link do
GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
end
def init(:ok) do
# Process.flag(:trap_exit, true)
{:ok, []}
end
def some_method(pid, input) do
GenServer.call(pid, {:some_method, input})
end
def handle_call({:some_method, input}, _from, state) do
# because we don't want to terminate GenServer use Task.async_nolink
task = Task.Supervisor.async_nolink(My.Task.Supervisor, fn ->
# raise argument error when passing binary
String.to_integer(input)
end)
{:reply, Task.await(task), state}
end
def handle_info({:EXIT, from, reason}, state) do
IO.inspect "handle_info::exit"
IO.inspect reason
{:noreply, state}
end
def handle_info({_ref, result}, state) do
IO.inspect "handle_info::result"
IO.inspect result
{:noreply, state}
end
def handle_info({:DOWN, _ref, :process, _pid, reason}, state) do
IO.inspect "handle_info::down"
IO.inspect reason
{:noreply, state}
end
def handle_info(msg, state) do
IO.inspect "handle_info"
IO.inspect msg
{:noreply, state}
end
end
I’ve read the docs from here regarding Task.Supervisor.async_link
: if you create a task using async_nolink
inside an OTP behaviour like GenServer, you should match on the message coming from the task inside your GenServer.handle_info/2
callback.
My problem is that handle_info is not called, I try to debug using observer attaching a trace to My.GenServer and I see that My.GenServer is receiving a :DOWN message:
Any solution to this problem ?
Thanks