next-ls icon indicating copy to clipboard operation
next-ls copied to clipboard

stdio buffer exception

Open AHBruns opened this issue 2 years ago • 16 comments

17:45:12.329 [error] Task #PID<0.355.0> started from NextLS.Buffer terminating
** (MatchError) no match of right hand side value: [",\\n    \\\"address\\\",\\n    \\\"street_address_line_2\\\",\\n    \\\"city\\\",\\n    \\\"state\\\",\\n    \\\"zip\\\"\\n  ]\\n\\n  @impl Oban.Worker\\n  def perform(%Oban.Job{args", " %{\\\"portal_id\\\" => _portal_id, \\\"contact_id\\\" => contact_id}}) do\\n    case Contact.get_contact_properties(", "lead_ranking, contact_id, @lead_ranking_properties) do\\n      {", "ok, ", "archived} ->\\n        ", "ok\\n\\n      {", "ok, properties} ->\\n        plan_for(\\n          rankability(properties[\\\"hs_lead_status\\\"]),\\n          nillify(properties[\\\"lead_rank\\\"]),\\n          nillify(properties[\\\"zip\\\"])\\n        ).(contact_id, properties)\\n\\n      error ->\\n        error\\n    end\\n  end\\n\\n  defp plan_for(_status, nil, nil), do", " &nothing/2\\n  defp plan_for(", "rankable, nil, _zip), do", " &create_lead_rank/2\\n  defp plan_for(", "unrankable, nil, _zip), do", " &nothing/2\\n  defp plan_for(_status, _lead_rank, nil), do", " &clear_lead_rank/2\\n  defp plan_for(", "rankable, _lead_rank, _zip), do", " &update_lead_rank/2\\n  defp plan_for(", "unrankable, _lead_rank, _zip), do", " &clear_lead_rank/2\\n\\n  defp nothing(_contact_id, _properties), do", " ", "ok\\n\\n  defp create_lead_rank(contact_id, properties) do\\n    set_lead_rank(contact_id, rank_for(properties))\\n  end\\n\\n  defp update_lead_rank(contact_id, %{\\\"lead_rank\\\" => lead_rank} = properties) do\\n    case rank_for(properties) do\\n      ^lead_rank -> ", "ok\\n      new_lead_rank -> set_lead_rank(contact_id, new_lead_rank)\\n    end\\n  end\\n\\n  defp clear_lead_rank(contact_id, _properties) do\\n    set_lead_rank(contact_id, \\\"\\\")\\n  end\\n\\n  defp rank_for(%{\\n         \\\"address\\\" => address,\\n         \\\"street_address_line_2\\\" => street_address_line_2,\\n         \\\"city\\\" => city,\\n         \\\"state\\\" => state,\\n         \\\"zip\\\" => zip\\n       }) do\\n    {", "ok, %{\\\"total_available_therapists\\\" => total_available_therapists}} =\\n      Serviceability.available_therapists(%{\\n        address_text", "\\n          [\\n            address,\\n            street_address_line_2,\\n            city,\\n            state,\\n            zip\\n          ]\\n          |> Enum.filter(fn\\n            nil -> false\\n            \\\"\\\" -> false\\n            _otherwise -> true\\n          end)\\n          |> Enum.join(\\\", \\\")\\n      })\\n\\n    Integer.to_string(total_available_therapists)\\n  end\\n\\n  defp set_lead_rank(contact_id, value) do\\n    Contact.set_contact_properties(", "lead_ranking, contact_id, %{\\\"lead_rank\\\" => value})\\n  end\\n\\n  defp nillify(\\\"\\\"), do", " nil\\n  defp nillify(nil), do", " nil\\n  defp nillify(value), do", " value\\n\\n  defp rankability(\\\"Patient - Suspect\\\"), do", " ", "rankable\\n  defp rankability(\\\"Patient - Qualified", " Ready to book\\\"), do", " ", "rankable\\n  defp rankability(_value), do", " ", "unrankable\\nend\\n\"}}}Content-Length", " 201"]
    (gen_lsp 0.6.0) lib/gen_lsp/communication/stdio.ex:73: GenLSP.Communication.Stdio.read_header/1
    (gen_lsp 0.6.0) lib/gen_lsp/communication/stdio.ex:40: GenLSP.Communication.Stdio.read/2
    (gen_lsp 0.6.0) lib/gen_lsp/buffer.ex:128: anonymous fn/4 in GenLSP.Buffer.read/2
    (elixir 1.15.5) lib/stream.ex:1626: Stream.do_resource/5
    (elixir 1.15.5) lib/enum.ex:4387: Enum.reverse/1
    (elixir 1.15.5) lib/enum.ex:3704: Enum.to_list/1
    (elixir 1.15.5) lib/task/supervised.ex:101: Task.Supervised.invoke_mfa/2
Function: #Function<0.64901786/0 in GenLSP.Buffer.read/2>
    Args: []

This is the error in the logs. It seems to be specific to files using Oban.

AHBruns avatar Oct 23 '23 23:10 AHBruns

I take it back, it's not just Oban related files.

AHBruns avatar Oct 23 '23 23:10 AHBruns

Can you give me the exact contents of the file that causes this?

You can email it to me if it's sensitive, but it's already error you pasted.

mhanberg avatar Oct 23 '23 23:10 mhanberg

defmodule Grimoire.PatientCentricSearch.LiteHubspotContactsSyncChunkWorker do
  @moduledoc false

  use Oban.Pro.Workers.Chunk,
    queue: :hubspot_requesters,
    by: [args: :profile],
    size: 100,
    timeout: 1000

  alias Grimoire.Bridges.Hubspot.Api.Contact
  alias Grimoire.PatientCentricSearch.LiteHubspotContact
  alias Grimoire.Repo

  require Logger

  @impl true
  def process([%{args: %{"profile" => profile}} | _] = jobs) do
    results =
      profile
      |> String.to_existing_atom()
      |> Contact.batch_get_contact_properties(
        jobs
        |> Stream.map(fn job ->
          Map.fetch!(job.args, "hs_object_id")
        end)
        |> Stream.uniq(),
        [
          "firstname",
          "middle_name",
          "lastname",
          "date_of_birth",
          "email",
          "address",
          "phone"
        ]
      )

    Enum.each(results, fn
      {hs_object_id, {:ok, :archived}} ->
        Repo.delete!(
          %LiteHubspotContact{hs_object_id: hs_object_id},
          stale_error_field: :hs_object_id,
          stale_error_message: "is already deleted"
        )

      {hs_object_id, {:ok, contact}} ->
        properties = [
          first_name: contact["firstname"],
          middle_name: contact["middle_name"],
          last_name: contact["lastname"],
          date_of_birth: contact["date_of_birth"],
          email: contact["email"],
          address: contact["address"],
          phone: contact["phone"],
          hs_object_id: hs_object_id
        ]

        # upsert
        Repo.insert!(
          struct!(LiteHubspotContact, properties),
          on_conflict: [set: properties],
          conflict_target: :hs_object_id
        )

      {hs_object_id, {:error, reason}} ->
        Logger.error("an error was returned when attempting to read hubspot contact #{hs_object_id}: #{inspect(reason)}")
    end)

    failed_jobs =
      Enum.filter(jobs, fn %{args: %{"hs_object_id" => hs_object_id}} ->
        case results[hs_object_id] do
          {:ok, _} -> false
          _ -> true
        end
      end)

    if Enum.empty?(failed_jobs) do
      :ok
    else
      {:error, "failed to sync", failed_jobs}
    end
  end
end

It's not particularly sensitive. Blowing away _build and .elixir-tools does seems to have fixed the issue fwiw.

AHBruns avatar Oct 24 '23 00:10 AHBruns

Also what is your elixir and otp versions and what is your OS

mhanberg avatar Oct 24 '23 00:10 mhanberg

Are there any files that might have strange Unicode characters in them?

mhanberg avatar Oct 24 '23 00:10 mhanberg

Nothing comes to mind with strange unicode characters. Also, after blowing everything away it did start happening again, thought this time with a different error (different file, btw):

19:47:39.727 [error] GenServer NextLS.Buffer terminating
** (Jason.DecodeError) unexpected end of input at position 2988
    (jason 1.4.1) lib/jason.ex:92: Jason.decode!/2
    (gen_lsp 0.6.0) lib/gen_lsp/buffer.ex:82: GenLSP.Buffer.handle_cast/2
    (stdlib 5.0.2) gen_server.erl:1103: :gen_server.try_handle_cast/3
    (stdlib 5.0.2) gen_server.erl:1165: :gen_server.handle_msg/6
    (stdlib 5.0.2) proc_lib.erl:241: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", {:incoming, "\n{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/didSave\",\"params\":{\"textDocument\":{\"uri\":\"file:///Users/alexbruns/code/luna/grimoire/lib/grimoire_web/live/patient_centric_search/search_bar.ex\"},\"text\":\"defmodule GrimoireWeb.PatientCentricSearchLive.SearchBar do\\n  @moduledoc false\\n\\n  use GrimoireWeb, :live_component\\n\\n  alias Grimoire.PatientCentricSearch\\n  alias GrimoireWeb.OmniUI\\n\\n  def search_bar(assigns) do\\n    ~H\\\"\\\"\\\"\\n    <.live_component module={__MODULE__} {assigns} />\\n    \\\"\\\"\\\"\\n  end\\n\\n  @impl true\\n  def render(assigns) do\\n    ~H\\\"\\\"\\\"\\n    <div>\\n      <.form for={@form} phx-target={@myself} phx-change=\\\"search\\\" phx-debounce={300}>\\n        <OmniUI.text_input field={{@form, :query}} placeholder=\\\"Search for a patient...\\\" />\\n      </.form>\\n    </div>\\n    \\\"\\\"\\\"\\n  end\\n\\n  @impl true\\n  def mount(socket) do\\n    {:ok, initialize_assigns(socket)}\\n  end\\n\\n  @impl true\\n  def update(assigns, socket) do\\n    {\\n      :ok,\\n      socket\\n      |> update_params(assigns.params)\\n      |> update_id(assigns.id)\\n    }\\n  end\\n\\n  @impl true\\n  def handle_event(\\\"search\\\", params, socket) do\\n    {:noreply, update_query(socket, params[\\\"form\\\"][\\\"query\\\"])}\\n  end\\n\\n  defp update_id(socket, new_id) do\\n    if socket.assigns.id != new_id do\\n      socket\\n      |> assign(:id, new_id)\\n      |> update_query(Map.get(socket.assigns.params, new_id, \\\"\\\"))\\n    else\\n      socket\\n    end\\n  end\\n\\n  defp initialize_assigns(socket) do\\n    socket\\n    |> assign(:id, nil)\\n    |> assign(:params, %{})\\n    |> assign(:query, \\\"\\\")\\n    |> assign(:form, form_from_query(\\\"\\\"))\\n  end\\n\\n  defp form_from_query(query) do\\n    to_form(%{\\\"query\\\" => query}, as: :form)\\n  end\\n\\n  defp update_params(socket, params) do\\n    if socket.assigns.params != params do\\n      socket\\n      |> assign(:params, params)\\n      |> update_query(Map.get(params, socket.assigns.id, \\\"\\\"))\\n    else\\n      socket\\n    end\\n  end\\n\\n  defp update_query(socket, query) do\\n    if socket.assigns.query != query do\\n      query\\n      |> PatientCentricSearch.search()\\n      |> emit_search_results()\\n\\n      socket\\n      |> assign(:query, query)\\n      |> update_form(form_from_query(query))\\n      |> sync_to_url()\\n    else\\n      socket\\n    end\\n  end\\n\\n  defp emit_search_results(search_results) do\\n    topic = \\\"patient_centric_search_live:\#{inspect(self())}\\\"\\n    Phoenix.PubSub.broadcast(Grimoire.PubSub, topic, {topic, :search_results, search_results})\\n  end\\n\\n  defp update_form(socket, new_form) do\\n    if socket.assigns.form != new_form do\\n      assign(socket, :form, new_form)\\n    else\\n      socket\\n    end\\n  end\\n\\n  defp sync_to_url(socket) do\\n    if Map.get(socket.assigns.params, socket.assigns.id, \\\"\\\") != socket.assigns.query do\\n      new_params = Map.put(socket.assigns.params, socket.assigns.id, socket.assigns.query)\\n      push_patch(socket, to: ~p\\\"/patient-centric-search?\#{new_params}\\\")\\n    else\\n      socket\\n    end\\n  end\\nend\\n\"}"}}
State: %{lsp: #PID<0.193.0>, comm: GenLSP.Communication.Stdio, comm_data: nil, awaiting_response: %{}}

Wrt versions:

Erlang/OTP 26 [erts-14.0.2] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit] [dtrace]

Elixir 1.15.7 (compiled with Erlang/OTP 26)

I'm on a mac.

AHBruns avatar Oct 24 '23 01:10 AHBruns

What editor?

mhanberg avatar Oct 24 '23 01:10 mhanberg

I'm finishing up some better debugging tools so hopefully after I release that you can update and this will become easier to track down.

mhanberg avatar Oct 24 '23 01:10 mhanberg

Assuming I don't figure it out earlier

mhanberg avatar Oct 24 '23 01:10 mhanberg

vs code

AHBruns avatar Oct 24 '23 01:10 AHBruns

I've been noticing this from time to time as well. Didn't open an issue yet because I cannot find a reliable way of reproducing it as it gets fixed when deleting the .elixir-tools folder and restarting the editor as @AHBruns says.

Will keep an eye on it and post a comment if I see it happening again.

crbelaus avatar Oct 24 '23 06:10 crbelaus

Since this is a GenLSP issue, I opened an issue over there. Will leave this one open tho as well to track it until I fix and update

https://github.com/elixir-tools/gen_lsp/issues/41

mhanberg avatar Oct 24 '23 14:10 mhanberg

I am having trouble reproducing this with a property test, but @fhunleth says he was seeing similar errors after seeing another error that he submitted a patch (#331) for.

I will keep this open, but after I release this patch on v0.15, please let me know if you continue to see errors like this.

Thanks!

mhanberg avatar Nov 04 '23 14:11 mhanberg

Hey folks, just wanted to note that I'm running into this issue maybe every 2 hours now. It happens when NextLS compiles my dependencies (I don't know why it does that though because I haven't changed my dependencies in a few days). This prevents my editor (VSCode) from saving the file, which is blocking me from coding. I usually just restart my VSCode and then the error goes away.

I'll just drop the full output here in the hope that you find an error.

[NextLS] Unchecked dependencies for environment dev:
* bcrypt_elixir (Hex package)
[NextLS]   the dependency is not available, run "mix deps.get"
# </------ 50 other dependencies with the same error message ---------->
[Warn  - 20:03:56] [NextLS] Unexpected compiler response: {:error, %{message: "Can't continue due to errors on dependencies", __struct__: Mix.Error, __exception__: true, mix: 1}}
[Error - 20:05:10] ** (SyntaxError) nofile:44:7: keyword argument must be followed by space after: https:
    |
 44 |       some compile error here # <- I forgot a comma after a field in a map
    |       ^

[NextLS] Unchecked dependencies for environment dev:
* bcrypt_elixir (Hex package)
[NextLS]   the dependency is not available, run "mix deps.get"
# </------ 50 other dependencies with the same error message ---------->
[Warn  - 20:05:16] [NextLS] Unexpected compiler response: {:error, %{message: "Can't continue due to errors on dependencies", __struct__: Mix.Error, __exception__: true, mix: 1}}

[NextLS]   the dependency is not available, run "mix deps.get"
# </------ 50 other dependencies with the same error message ---------->
[Warn  - 20:05:25] [NextLS] Unexpected compiler response: {:error, %{message: "Can't continue due to errors on dependencies", __struct__: Mix.Error, __exception__: true, mix: 1}}

20:05:43.117 [error] GenServer NextLS.Buffer terminating
** (Jason.DecodeError) unexpected end of input at position 258
    (jason 1.4.1) lib/jason.ex:92: Jason.decode!/2
    (gen_lsp 0.6.2) lib/gen_lsp/buffer.ex:82: GenLSP.Buffer.handle_cast/2
    (stdlib 5.1.1) gen_server.erl:1103: :gen_server.try_handle_cast/3
    (stdlib 5.1.1) gen_server.erl:1165: :gen_server.handle_msg/6
    (stdlib 5.1.1) proc_lib.erl:241: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", {:incoming, "\n{\"jsonrpc\":\"2.0\",\"id\":2296,\"method\":\"textDocument/completion\",\"params\":{\"textDocument\":{\"uri\":\"file:///Users/peterullrich/Development/vcp/lib/app_web/live/some_path_and_live_view.ex\"},\"position\":{\"line\":39,\"character\":23},\"context\":{\"triggerKind\":1}}"}}
State: %{lsp: #PID<0.193.0>, comm: GenLSP.Communication.Stdio, comm_data: nil, awaiting_response: %{}}

PJUllrich avatar Dec 08 '23 19:12 PJUllrich

@PJUllrich thank you! And sorry it's happening so frequently.

I'm starting to think this might be a VScode thing, as I haven't ever run into this personally (in neovim).

I'll have to run VSCode for a day to see if I can reproduce.

mhanberg avatar Dec 08 '23 21:12 mhanberg

No worries :) all the more reason to finally switch to Neovim maybe 😬

PJUllrich avatar Dec 08 '23 21:12 PJUllrich