lexical-lsp / lexical

Lexical is a next-generation elixir language server
888 stars 82 forks source link

Getting 'Module is not loaded and could not be found', despite it exists #820

Closed mat-hek closed 2 months ago

mat-hek commented 2 months ago

I'm getting an error like this

image

Interestingly, 'go to definition' works for the 'not found' module 🤔 It happens mostly for modules from deps, however, sometimes also for the project modules. In the latter case, re-saving the problematic module helps. Restarting Lexical or even the editor doesn't help.

Extension version: 0.0.18 Lexical version: probably the latest, as that's what the extension says it downloads

When this happens, lexical.log shows the following error:

14:04:59.912 [info] Resolved entity: {:call, Kernel, :defmodule, 2}
14:05:01.218 [info] Response %{error: nil, id: 278, result: %{__struct__: LXical.Document.Changes, document: #Inspect.Error<
  got UndefinedFunctionError with message:

      """
      function Code.Identifier.inspect_as_atom/1 is undefined or private
      """

  while inspecting:

      %{
        version: 22,
        path: "/Users/matheksm/m/proj/lib/proj/elixir_stream/source.ex",
        uri: "file:///Users/matheksm/m/proj/lib/proj/elixir_stream/source.ex",
        __struct__: LXical.Document,
        lines: %Lines<"defmodule Source do..."(80 lines)>,
        dirty?: true,
        language_id: "elixir"
      }

  Stacktrace:

    (elixir 1.17.2) Code.Identifier.inspect_as_atom(LXical.Document)
    (lx_lexical_shared 0.5.0) lib/lexical/document.ex:25: Inspect.LXical.Document.inspect/2
    (elixir 1.17.2) lib/inspect/algebra.ex:347: Inspect.Algebra.to_doc/2
    (elixir 1.17.2) lib/inspect.ex:287: Inspect.List.keyword/2
    (elixir 1.17.2) lib/inspect/algebra.ex:478: Inspect.Algebra.container_each/6
    (elixir 1.17.2) lib/inspect/algebra.ex:455: Inspect.Algebra.container_doc/6
    (elixir 1.17.2) lib/inspect/algebra.ex:347: Inspect.Algebra.to_doc/2
    (elixir 1.17.2) lib/inspect.ex:287: Inspect.List.keyword/2

>, edits: []}, __struct__: LXical.Protocol.Responses.Formatting}

and project.log shows the following error:

2024-08-23T14:05:01.353430+02:00 error: Process #PID<0.1329.0> on node :"project-proj-48722@127.0.0.1" raised an exception, ** (Mix.Error) Can't continue due to errors on dependencies, (mix 1.17.2) lib/mix.ex:588: Mix.raise/2, (mix 1.17.2) lib/mix/tasks/deps.loadpaths.ex:48: Mix.Tasks.Deps.Loadpaths.run/1, (mix 1.17.2) lib/mix/task.ex:495: anonymous fn/3 in Mix.Task.run_task/5, (mix 1.17.2) lib/mix/tasks/loadpaths.ex:37: Mix.Tasks.Loadpaths.run/1, (mix 1.17.2) lib/mix/task.ex:495: anonymous fn/3 in Mix.Task.run_task/5, (mix 1.17.2) lib/mix/tasks/compile.ex:153: Mix.Tasks.Compile.run/1, (mix 1.17.2) lib/mix/task.ex:495: anonymous fn/3 in Mix.Task.run_task/5, (lx_remote_control 0.5.0) lib/lexical/remote_control/build/isolation.ex:12: anonymous fn/2 in LXical.RemoteControl.Build.Isolation.invoke/1
zachallaun commented 2 months ago

Thanks for the report!

I'm not 100% sure that the error uncovered in the logs is related to the module not being found, but it's probably worth pulling on both threads. Let's start with the error:

Code.Identifier.inspect_as_atom/1 was a function in the private Code.Identifier module until Elixir 1.14, so it makes sense that a call to it would raise an error on Elixir 1.17.2 (which seems to be the runtime version from the stacktrace). That function isn't used anywhere in Lexical nor in elixir_sense (which Lexical uses).

Can you please do the following:

mat-hek commented 2 months ago

Somehow I totally forgot to try removing .lexical... It even may have been created by the previous version of Lexical. Now it seems to work ;)

Anyway, in case you need it, the project's been compiling normally outside of Lexical, and the deps are:

      {:membrane_core, "~> 1.1"},
      {:membrane_webrtc_plugin, "~> 0.21.0"},
      {:membrane_opus_plugin, "~> 0.20.0"},
      {:membrane_aac_plugin, "~> 0.18.0"},
      {:membrane_aac_fdk_plugin, "~> 0.18.0"},
      {:membrane_h26x_plugin, "~> 0.10.0"},
      {:membrane_h264_ffmpeg_plugin, "~> 0.32.0"},
      {:membrane_mp4_plugin,
       github: "membraneframework/membrane_mp4_plugin", branch: "wip-avc3", override: true},
      {:membrane_realtimer_plugin, "~> 0.9.0"},
      {:membrane_http_adaptive_stream_plugin, "~> 0.18.0"},
      {:membrane_rtmp_plugin, "~> 0.24.0"},
      {:membrane_ffmpeg_swresample_plugin, "~> 0.20.0"},
      {:membrane_hackney_plugin, "~> 0.11.0"},
      {:burrito, "~> 1.0", runtime: burrito?()},
      {:membrane_ffmpeg_swscale_plugin, ">= 0.0.0"},
      {:image, ">= 0.0.0"},
      {:ex_doc, ">= 0.0.0", only: :dev, runtime: false},
      {:dialyxir, ">= 0.0.0", only: :dev, runtime: false},
      {:credo, ">= 0.0.0", only: :dev, runtime: false}

Thanks for your help ;)

zachallaun commented 2 months ago

I'm glad that fixed it! This is still an area Lexical could improve on. Users shouldn't ever have to delete the .lexical directory, even between versions, but there are clearly some edge cases (probably to do with Elixir/OTP version updates).

@scohen A maybe-not-good idea: If Lexical encounters errors the first time it compiles a project, what if it recompiled everything from scratch (maybe silently)? The idea being that projects are usually saved in a healthy state, so if Lexical is failing to compile a project the first time it's opened, it may be a faulty build cache.

mat-hek commented 2 months ago

Maybe also invalidate the cache after the Lexical update? 🤔