Repository navigation
Do not compile when loading formatter plugins in non mix projects - #1279
Merged
Merged
Conversation
SourceFile.formatter_for/4 passed the non-compiling plugin loader only in the mix project branch. In the non mix branch the default ElixirLSFormat plugin loader ran mix loadpaths and mix compile in the calling process (the Server GenServer for completion requests). An aborted compile left the compiler worker reply in the Server mailbox and crashed it with a FunctionClauseError in handle_info/2. Use the same non-compiling plugin loader in both branches and add a catch-all handle_info/2 to the Server that logs and ignores unexpected messages.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Crash
Reported on Elixir 1.19.5:
Root cause
The
{ref, {:error, errors, %{runtime_warnings: ..., compile_warnings: ...}}}message is the final reply Mix's Elixir compiler worker sends to the process that calledMix.Task.run("compile"). So a compile ran inside the Server process, got aborted, and its late reply landed in the Server mailbox.SourceFile.formatter_for/4passes a non-compilingplugin_loaderin the mix project branch, but not in the non mix project branch. ThereMix.Tasks.ElixirLSFormat.formatter_for_file/2falls back to its default loader, which runsmix loadpathsandmix compilewhenever.formatter.exslists plugins. The completion handler callsformatter_for/4synchronously in the Server process, and the surroundingcatchswallowed the aborted compile, leaving the stray message behind.Fix
SourceFile.plugin_loader/1and use it in both branches. Plugins that are not loaded are skipped with a warning, the same as in mix projects.handle_info/2toElixirLS.LanguageServer.Serverthat logs and ignores unexpected messages, so a stray message can no longer bring down the server.Tests
formatter_for/4in a non mix project whose.formatter.exslists one loaded and one missing plugin: it returns options, the loaded plugin is used and no compile runs. Before this change it went through the Mix loader and returned{:error, "Formatter plugin ... cannot be found"}.