Skip to content

Commit b3f00a5

Browse files
authored
DocumentSymbols provider handles compilation errors gracefully (#186)
Rather than throwing an exception (which causes the spawned process to crash) the DocumentSymbols provider will now simply return an error. This is beneficial because this is very much an expected error and thus it is confusing to show the exception in the logs. Possibly there are also performance benefits to this as well. Ideally the DocumentSymbols provider could still return valid symbols in this case, but that is currently infeasible.
1 parent 9637725 commit b3f00a5

File tree

2 files changed

+36
-12
lines changed

2 files changed

+36
-12
lines changed

apps/language_server/lib/language_server/providers/document_symbols.ex

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,32 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
1717
]
1818

1919
def symbols(uri, text, hierarchical) do
20-
symbols = list_symbols(text)
20+
case list_symbols(text) do
21+
{:ok, symbols} ->
22+
{:ok, build_symbols(symbols, uri, hierarchical)}
2123

22-
symbols =
23-
if hierarchical do
24-
Enum.map(symbols, &build_symbol_information_hierarchical(uri, &1))
25-
else
26-
symbols
27-
|> Enum.map(&build_symbol_information_flat(uri, &1))
28-
|> List.flatten()
29-
end
24+
{:error, :compilation_error} ->
25+
{:error, :server_error, "[DocumentSymbols] Compilation error while parsing source file"}
26+
end
27+
end
3028

31-
{:ok, symbols}
29+
defp build_symbols(symbols, uri, hierarchical)
30+
31+
defp build_symbols(symbols, uri, true) do
32+
Enum.map(symbols, &build_symbol_information_hierarchical(uri, &1))
33+
end
34+
35+
defp build_symbols(symbols, uri, false) do
36+
symbols
37+
|> Enum.map(&build_symbol_information_flat(uri, &1))
38+
|> List.flatten()
3239
end
3340

3441
defp list_symbols(src) do
35-
Code.string_to_quoted!(src, columns: true, line: 0)
36-
|> extract_modules()
42+
case Code.string_to_quoted(src, columns: true, line: 0) do
43+
{:ok, quoted_form} -> {:ok, extract_modules(quoted_form)}
44+
{:error, _error} -> {:error, :compilation_error}
45+
end
3746
end
3847

3948
# Identify and extract the module symbol, and the symbols contained within the module

apps/language_server/test/providers/document_symbols_test.exs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2395,4 +2395,19 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do
23952395
}
23962396
]
23972397
end
2398+
2399+
test "handles a file with compilation errors by returning an empty list" do
2400+
uri = "file://project/test.exs"
2401+
2402+
text = """
2403+
defmodule A do
2404+
def hello do
2405+
Hello.hi(
2406+
end
2407+
end
2408+
"""
2409+
2410+
assert {:error, :server_error, message} = DocumentSymbols.symbols(uri, text, true)
2411+
assert String.contains?(message, "Compilation error")
2412+
end
23982413
end

0 commit comments

Comments
 (0)