commanded/eventstore

FunctionClauseError on DBConnection.ConnectionError

janpieper opened this issue · 1 comments

We sometimes see the following error in our error logs:

ErlangError: Erlang error: {{:function_clause, [{EventStore.Storage.Subscription.Query, :handle_response, [error: %DBConnection.ConnectionError{message: "tcp recv: closed"}], [file: 'lib/event_store/storage/subscription.ex', line: 88]}, {EventStore.Storage.Subscription, :subscribe_to_stream, 5, [file: 'lib/event_store/storage/subscription.ex', line: 31]}, {EventStore.Subscriptions.SubscriptionFsm, :transition, 3, [file: 'lib/event_store/subscriptions/subscription_fsm.ex', line: 42]}, {EventStore.Subscriptions.Subscription, :handle_call, 3, [file: 'lib/event_store/subscriptions/subscription.ex', line: 188]}, {:gen_server, :try_handle_call, 4, [file: 'gen_server.erl', line: 661]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 690]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}]}, {GenServer, :call, [#PID<0.4880.186>, {:connect, #PID<0.4640.186>, [start_from: 0, mapper: #Function<3.89237498/1 in Commanded.EventStore.Adapters.EventStore.subscribe_to/4>]}, 5000]}}
  File "lib/gen_server.ex", line 989, in GenServer.call/3
  File "lib/commanded/event/handler.ex", line 458, in Commanded.Event.Handler.subscribe_to_events/1
  File "lib/commanded/event/handler.ex", line 396, in Commanded.Event.Handler.handle_cast/2
  File "gen_server.erl", line 637, in :gen_server.try_dispatch/4
  File "gen_server.erl", line 711, in :gen_server.handle_msg/6
  File "proc_lib.erl", line 249, in :proc_lib.init_p_do_apply/3

The FunctionClauseError occurs because there is no implementation to handle an {:error, _} tuple in EventStore.Storage.Subscription.Query:

defp handle_response({:ok, %Postgrex.Result{num_rows: 0}}),
do: {:error, :subscription_not_found}
defp handle_response({:ok, %Postgrex.Result{rows: rows}}),
do: {:ok, Subscription.Adapter.to_subscription(rows)}

It's the same for EventStore.Storage.Subscription.All.

There are implementations for handling an {:error, _} tuple for all other EventStore.Storage.Subscription.* modules. Example:

defp handle_response({:error, error}, stream_uuid, subscription_name) do
_ =
Logger.warn(fn ->
"Failed to delete subscription to stream \"#{stream_uuid}\" named \"#{subscription_name}\" due to: #{
error
}"
end)
{:error, error}
end

Thanks for bug report @janpieper we should add matches to cover these missing error cases.