couchbeam icon indicating copy to clipboard operation
couchbeam copied to clipboard

Database disconnect throws unmatched clause error on gen_changes

Open javierg opened this issue 2 years ago • 2 comments

I am using the gen_changes behavior and if the server disconnects the app throws an exception on

    State2 = case Msg of
        {done, LastSeq} ->
            State#gen_changes_state{last_seq=LastSeq};
        {change, Change} ->
            Seq = couchbeam_doc:get_value(<<"seq">>, Change),
            State#gen_changes_state{last_seq=Seq}

As hackney returns {hackney_response, Ref, done}

Is there something I am missing? I want my application to just log the error as it is done by /couchbeam_changes_stream.erl and let the handle_change callback in my app to decide what to do (wait for reconnection, or exit.

As a workaround I patched the library to set the state when error to the response from the server.

Thanks for the amazing job!

javierg avatar Oct 11 '23 23:10 javierg

@javierg can you share the exception raised? This should be normally catched. If you can also please share the portion of your code that intiate the change.

benoitc avatar Oct 12 '23 12:10 benoitc

@benoitc

This is the exception raised

[error] GenServer #PID<0.2841.0> terminating
** (CaseClauseError) no case clause matching: {:error, {:hackney_response, #Reference<0.2008468710.2789736451.184912>, :done}}
    (couchbeam 1.4.2) /Users/javierg/contentinator/deps/couchbeam/src/gen_changes.erl:126: :gen_changes.handle_info/2
    (stdlib 3.17) gen_server.erl:695: :gen_server.try_dispatch/4
    (stdlib 3.17) gen_server.erl:771: :gen_server.handle_msg/6
    (stdlib 3.17) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Last message: {#Reference<0.2008468710.2789736452.179287>, {:error, {:hackney_response, #Reference<0.2008468710.2789736451.184912>, :done}}}
State: {:gen_changes_state, #Reference<0.2008468710.2789736452.179287>, "3686538-g1AAAACheJzLYWBgYMpgTmEQTM4vTc5ISXLIyU9OzMnILy7JAUklMiTV____PyuDOYlBRv9bLlCM3dTSJDnFIhGbHjwm5bEASYYGIPUfbqDAFLCBZmZpJmYG5ti0ZgEAuWYyfg", CouchDb.Observer, %{}, {:db, {:server, "http://localhost:8980", [basic_auth: {"root", "123"}]}, "bs", [basic_auth: {"root", "123"}]}, [feed: :longpoll, filter: "_doc_ids", doc_ids: ["publisher/amco", "publisher/sep"], heartbeat: 9000]}

The code that starts the gen_changes is on a modules' start_link

  @behaviour :gen_changes

  def start_link(db, opts) do
    :gen_changes.start_link(__MODULE__, db, opts, [])
  end

  @impl true
  def init([]) do
    {:ok, nil}
  end

  def child_spec(opts) do
    %{
      id: __MODULE__,
      start: {__MODULE__, :start_link, opts},
      type: :supervisor,
      restart: :permanent
    }
  end

  ...

javierg avatar Oct 12 '23 13:10 javierg