Skip to content

Commit c9f05dd

Browse files
authored
Handle formatting errors when file has syntax errors (#192)
Otherwise we're logging an exception which makes the logs unecessarily noisy and this should be an expected case. Also handle the case where the source_file is not currently in state
1 parent 9cbf703 commit c9f05dd

File tree

4 files changed

+82
-3
lines changed

4 files changed

+82
-3
lines changed

apps/language_server/lib/language_server/providers/formatting.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ defmodule ElixirLS.LanguageServer.Providers.Formatting do
2525

2626
{:error, :internal_error, msg}
2727
end
28+
rescue
29+
_e in [TokenMissingError, SyntaxError] ->
30+
{:error, :internal_error, "Unable to format due to syntax error"}
2831
end
2932

3033
# If in an umbrella project, the cwd might be set to a sub-app if it's being compiled. This is

apps/language_server/lib/language_server/server.ex

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,8 +475,14 @@ defmodule ElixirLS.LanguageServer.Server do
475475
end
476476

477477
defp handle_request(formatting_req(_id, uri, _options), state) do
478-
fun = fn -> Formatting.format(state.source_files[uri], uri, state.project_dir) end
479-
{:async, fun, state}
478+
case state.source_files[uri] do
479+
nil ->
480+
{:error, :server_error, "Missing source file", state}
481+
482+
source_file ->
483+
fun = fn -> Formatting.format(source_file, uri, state.project_dir) end
484+
{:async, fun, state}
485+
end
480486
end
481487

482488
defp handle_request(signature_help_req(_id, uri, line, character), state) do
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
defmodule ElixirLS.LanguageServer.Providers.FormattingTest do
2+
use ExUnit.Case
3+
alias ElixirLS.LanguageServer.Providers.Formatting
4+
5+
test "Formats a file" do
6+
uri = "file://project/file.ex"
7+
8+
text = """
9+
defmodule MyModule do
10+
require Logger
11+
12+
def dummy_function() do
13+
Logger.info "dummy"
14+
end
15+
end
16+
"""
17+
18+
source_file = %ElixirLS.LanguageServer.SourceFile{
19+
text: text,
20+
version: 1,
21+
dirty?: true
22+
}
23+
24+
project_dir = "/project"
25+
26+
assert {:ok, changes} = Formatting.format(source_file, uri, project_dir)
27+
28+
assert changes == [
29+
%{
30+
"newText" => ")",
31+
"range" => %{
32+
"end" => %{"character" => 23, "line" => 4},
33+
"start" => %{"character" => 23, "line" => 4}
34+
}
35+
},
36+
%{
37+
"newText" => "(",
38+
"range" => %{
39+
"end" => %{"character" => 16, "line" => 4},
40+
"start" => %{"character" => 15, "line" => 4}
41+
}
42+
}
43+
]
44+
end
45+
46+
test "returns an error when formatting a file with a syntax error" do
47+
uri = "file://project/file.ex"
48+
49+
text = """
50+
defmodule MyModule do
51+
require Logger
52+
53+
def dummy_function() do
54+
Logger.info("dummy
55+
end
56+
end
57+
"""
58+
59+
source_file = %ElixirLS.LanguageServer.SourceFile{
60+
text: text,
61+
version: 1,
62+
dirty?: true
63+
}
64+
65+
project_dir = "/project"
66+
67+
assert {:error, :internal_error, msg} = Formatting.format(source_file, uri, project_dir)
68+
assert String.contains?(msg, "Unable to format")
69+
end
70+
end

apps/language_server/test/providers/workspace_symbols_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbolsTest do
2-
alias ElixirLS.LanguageServer.Providers.WorkspaceSymbols
32
use ExUnit.Case
3+
alias ElixirLS.LanguageServer.Providers.WorkspaceSymbols
44

55
setup_all do
66
pid =

0 commit comments

Comments
 (0)