Reputation: 755
I have some code I would like to run in a task but it may throw an error. I have tried wrapping in a try/rescue however the error is not caught.
try do
Supervisor.start_link([ {Task, fn -> raise "kaboom" end}], strategy: :one_for_one)
rescue
RuntimeError -> "Error!"
end
I was hoping for "Error!" to be printed however i get -
(RuntimeError) kaboom
(stdlib) erl_eval.erl:678: :erl_eval.do_apply/6
(elixir) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Function: #Function<20.128620087/0 in :erl_eval.expr/5>
Args: []
{:ok, #PID<0.332.0>}
Is there any way to handle exceptions raised inside of a task from it's instigator?
Thanks
Upvotes: 1
Views: 576
Reputation: 121000
Task
is started as a separated process. The intercommunication of two processes can only be exchanging messages. One cannot expect to rescue
anything happened in one process from another process—processes are isolated.
One might rescue
inside a callee process (a task itself,) or simply start a task as :transient
and check the outcome, but this is an attempt to reinvent a functionality already provided by OTP.
Check linking chapter in the documentation.
If all you want would be to retry on occasional exception raised, start the task supervised and let it raise and crash, OTP will take care of everything else, including restarts, etc.
If you need to try once and react somehow on the exception raised, you probably should reconsider the architecture and start the monitored process instead, trapping exits.
Upvotes: 3