cqex icon indicating copy to clipboard operation
cqex copied to clipboard

Fix: Connection closed error creates case clause exception

Open dylan-chong opened this issue 2 years ago • 0 comments

When Scylla dies while a query is in progress, we get a CaseClauseError where the unmatched value is {{"INSERT INTO events_v4 (...) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", %{...}}, {:error, :connection_closed}}. I've added a new case clause at the failing point to create an CQEx.Error appropriately.

I've tested that this works by commenting out some code in the library, replicating the issue, and fixing it

# lib/cqex/query.ex
  def call(c, q) do
    client = nil#CQEx.Client.get(c)

    # case q do
      # %CQEx.Query{statement: statement, values: values} when is_binary(statement) ->
        # {{statement, values}, :cqerl.run_query(client, convert(q))}

      # %CQEx.Query{} ->
        # :cqerl.run_query(client, convert(q))

      # any ->
        # :cqerl.run_query(client, any)
    # end
    {{"INSERT INTO events_v4 (...) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", %{}}, {:error, :connection_closed}}
    |> case do
      {_, {:ok, result}} ->
        {:ok, CQEx.Result.convert(result, client)}

      {:ok, result} ->
        {:ok, CQEx.Result.convert(result, client)}

      {:error, {:error, {reason, stacktrace}}} ->
        {:error, %{msg: ":cqerl processing error: #{reason}", acc: stacktrace}}

      {{s, v}, {:error, {code, message, _extras}}} ->
        {:error,
         %{msg: "#{message} (Code #{code})\nStatement: #{s}\nValues: #{inspect(v)}", acc: []}}

      {{s, v}, {:error, e}} ->
        {:error,
         %{msg: "#{inspect(e)} \nStatement: #{s}\nValues: #{inspect(v)}", acc: []}}

      {:error, {code, message, _extras}} ->
        {:error, %{msg: "#{message} (Code #{code})", acc: []}}
    end
  end

Test by running

recompile; CQEx.Query.call(nil, nil)
#  also
recompile; CQEx.Query.call!(nil, nil)

dylan-chong avatar May 12 '22 06:05 dylan-chong