From f8b59f4eb97389bb322cd950d7e5bf2bbfdaaa6f Mon Sep 17 00:00:00 2001 From: Zach Allaun Date: Thu, 5 Sep 2024 11:14:23 -0400 Subject: [PATCH 1/2] Convert all exceptions in config files into diagnostics --- .../build/document/compilers/config.ex | 45 ++++++++++++------- .../lib/lexical/remote_control/build/error.ex | 20 ++------- .../remote_control/build/error/location.ex | 14 ++++++ .../build/document/compilers/config_test.exs | 19 ++++++++ 4 files changed, 64 insertions(+), 34 deletions(-) diff --git a/apps/remote_control/lib/lexical/remote_control/build/document/compilers/config.ex b/apps/remote_control/lib/lexical/remote_control/build/document/compilers/config.ex index d01319677..d135f5805 100644 --- a/apps/remote_control/lib/lexical/remote_control/build/document/compilers/config.ex +++ b/apps/remote_control/lib/lexical/remote_control/build/document/compilers/config.ex @@ -6,6 +6,9 @@ defmodule Lexical.RemoteControl.Build.Document.Compilers.Config do alias Lexical.Document alias Lexical.Plugin.V1.Diagnostic alias Lexical.RemoteControl.Build + alias Lexical.RemoteControl.Build.Error.Location + + @elixir_source "Elixir" @behaviour Build.Document.Compiler require Logger @@ -49,7 +52,7 @@ defmodule Lexical.RemoteControl.Build.Document.Compilers.Config do {:ok, []} rescue e -> - {:error, [to_result(document, e)]} + {:error, [to_result(document, e, __STACKTRACE__)]} end end @@ -73,33 +76,41 @@ defmodule Lexical.RemoteControl.Build.Document.Compilers.Config do end end - defp to_result(%Document{} = document, %CompileError{} = error) do - Diagnostic.Result.new(document.uri, error.line, Exception.message(error), :error, "Elixir") + defp to_result(document, error, stack \\ []) + + defp to_result(%Document{} = document, %CompileError{} = error, _stack) do + Diagnostic.Result.new( + document.uri, + error.line, + Exception.message(error), + :error, + @elixir_source + ) end - defp to_result(%Document{} = document, %error_type{} = error) + defp to_result(%Document{} = document, %error_type{} = error, _stack) when error_type in [SyntaxError, TokenMissingError] do Diagnostic.Result.new( document.uri, {error.line, error.column}, Exception.message(error), :error, - "Elixir" + @elixir_source ) end - defp to_result(%Document{} = document, %{ - position: position, - message: message, - severity: severity - }) do - Diagnostic.Result.new( - document.path, - position, - message, - severity, - "Elixir" - ) + defp to_result( + %Document{} = document, + %{position: position, message: message, severity: severity}, + _stack + ) do + Diagnostic.Result.new(document.path, position, message, severity, @elixir_source) + end + + defp to_result(%Document{} = document, %{__exception__: true} = exception, stack) do + message = Exception.message(exception) + position = Location.stack_to_position(stack) + Diagnostic.Result.new(document.path, position, message, :error, @elixir_source) end defp reject_logged_messages(results) do diff --git a/apps/remote_control/lib/lexical/remote_control/build/error.ex b/apps/remote_control/lib/lexical/remote_control/build/error.ex index 50f6d97d9..f1ae13fe4 100644 --- a/apps/remote_control/lib/lexical/remote_control/build/error.ex +++ b/apps/remote_control/lib/lexical/remote_control/build/error.ex @@ -146,7 +146,7 @@ defmodule Lexical.RemoteControl.Build.Error do mfa = {module, function, arity} mfa_to_position(mfa, quoted_ast) else - stack_to_position(stack) + Location.stack_to_position(stack) end Result.new(source.uri, position, message, :error, @elixir_source) @@ -182,7 +182,7 @@ defmodule Lexical.RemoteControl.Build.Error do if pipe_or_struct? or expanding? do Location.context_to_position(context) else - stack_to_position(stack) + Location.stack_to_position(stack) end Result.new(source.uri, position, message, :error, @elixir_source) @@ -195,7 +195,7 @@ defmodule Lexical.RemoteControl.Build.Error do ExUnit.DuplicateDescribeError ] do message = Exception.message(exception) - position = stack_to_position(stack) + position = Location.stack_to_position(stack) Result.new(source.uri, position, message, :error, @elixir_source) end @@ -281,20 +281,6 @@ defmodule Lexical.RemoteControl.Build.Error do end end - defp stack_to_position([{_, target, _, _} | rest]) - when target not in [:__FILE__, :__MODULE__] do - stack_to_position(rest) - end - - defp stack_to_position([{_, target, _, context} | _rest]) - when target in [:__FILE__, :__MODULE__] do - Location.context_to_position(context) - end - - defp stack_to_position([]) do - nil - end - defp do_message_to_diagnostic(_, "") do nil end diff --git a/apps/remote_control/lib/lexical/remote_control/build/error/location.ex b/apps/remote_control/lib/lexical/remote_control/build/error/location.ex index 7d983676d..d8f4e92c4 100644 --- a/apps/remote_control/lib/lexical/remote_control/build/error/location.ex +++ b/apps/remote_control/lib/lexical/remote_control/build/error/location.ex @@ -6,6 +6,20 @@ defmodule Lexical.RemoteControl.Build.Error.Location do require Logger + def stack_to_position([{_, target, _, _} | rest]) + when target not in [:__FILE__, :__MODULE__] do + stack_to_position(rest) + end + + def stack_to_position([{_, target, _, context} | _rest]) + when target in [:__FILE__, :__MODULE__] do + context_to_position(context) + end + + def stack_to_position([]) do + nil + end + def context_to_position(context) do case {context[:line], context[:column]} do {nil, nil} -> diff --git a/apps/remote_control/test/lexical/remote_control/build/document/compilers/config_test.exs b/apps/remote_control/test/lexical/remote_control/build/document/compilers/config_test.exs index d4515078a..d42cb8446 100644 --- a/apps/remote_control/test/lexical/remote_control/build/document/compilers/config_test.exs +++ b/apps/remote_control/test/lexical/remote_control/build/document/compilers/config_test.exs @@ -121,6 +121,25 @@ defmodule Lexical.RemoteControl.Build.Document.Compilers.ConfigTest do assert result.source == "Elixir" end + test "it produces diagnostics for arbitrary exceptions" do + assert {:error, [result]} = + ~q[ + import Config + + System.fetch_env!("_LEXICAL_NON_EXISTING_ENV_VAR_") + ] + |> document() + |> compile() + + assert result.message =~ "could not fetch environment variable" + assert result.severity == :error + assert result.source == "Elixir" + + if Features.with_diagnostics?() do + assert result.position == 3 + end + end + test "it produces no diagnostics on success" do assert {:ok, []} = ~q[ From 15c4df54fe1638d6eef431bde384a6d5bbcb224a Mon Sep 17 00:00:00 2001 From: Zach Allaun Date: Thu, 5 Sep 2024 14:04:18 -0400 Subject: [PATCH 2/2] Fix mise setup in integration tests --- integration/boot/set_up_mise.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/integration/boot/set_up_mise.sh b/integration/boot/set_up_mise.sh index 87783bb65..17d23e0e3 100755 --- a/integration/boot/set_up_mise.sh +++ b/integration/boot/set_up_mise.sh @@ -27,7 +27,6 @@ chmod +x ./mise eval "$(./mise activate bash)" export KERL_CONFIGURE_OPTIONS="--disable-debug --without-javac --without-termcap --without-wx" -./mise plugin install -y erlang ./mise use --global "erlang@$ERLANG_VERSION" ./mise plugins install -y elixir