I currently have a simple Genserver which connects to RabbitMQ. I’ve followed the documentation about creating a stable connection:
This essentially amounts to a handle_info
function which matches the :DOWN
event and then retries the connection:
def handle_info({:DOWN, _, :process, _pid, exception}, _) do
IO.puts "[*] connection DOWN, retrying"
{:ok, chan} = rabbitmq_connect
{:noreply, chan}
end
This works fine. However, I now want to capture these events. As an aside, I’d be interested in whether others would treat this as an exception or an event? I’m using Sentry to capture the exception like so:
def handle_info({:DOWN, _, :process, _pid, exception}, _) do
IO.puts "[*] connection DOWN, retrying"
Sentry.capture_exception(
exception,
[stacktrace: System.stacktrace(), extra: %{extra: "results"}])
{:ok, chan} = rabbitmq_connect
{:noreply, chan}
end
However, the issue here is Sentry.capture_exception
returns something such as (from a Task
):
{#Reference<0.4047852952.893648897.15807>,
{:ok, “9593df97c5ee40d182621ffc79b511af”}}
…and my Genserver crashes/complains because I’m not handling it. It then restarts and the connection is back up. Great, but I’d prefer it didn’t crash and skipped over Sentry.capture_exception
to run rabbitmq_connect
.
I then added a catch-all handle_info/2
but that doesn’t work because it is now catching {:basic_consume_ok, etc}
which the RabbitMQ library is producing when it connects.
Error:
[error] GenServer #PID<0.509.0> terminating
** (FunctionClauseError) no function clause matching in App.Channels.Results.handle_info/2
App.Channels.Results.handle_info({#Reference<0.3115891151.2776891395.93003>, {:ok, “cba31070d98a4e75aa4dec6b1b627b56”}}, %AMQP.Channel{conn: %AMQP.Connection{pid: #PID<0.531.0>}, pid: #PID<0.542.0>})
(stdlib) gen_server.erl:616: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:686: :gen_server.handle_msg/6
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: {#Reference<0.3115891151.2776891395.93003>, {:ok, “cba31070d98a4e75aa4dec6b1b627b56”}}
State: %AMQP.Channel{conn: %AMQP.Connection{pid: #PID<0.531.0>}, pid: #PID<0.542.0>}
My question is - how do I handle this properly? Can I not have my GenServer ignore the return from Sentry
? Will I have to create a handle_info
specifically for that? Little confused.