Skip to content

Commit 3f0708b

Browse files
committed
instrument various errors
1 parent ed3552c commit 3f0708b

File tree

8 files changed

+161
-29
lines changed

8 files changed

+161
-29
lines changed

apps/elixir_ls_debugger/lib/debugger/server.ex

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,34 @@ defmodule ElixirLS.Debugger.Server do
182182
{:ok, state}
183183
end
184184

185+
@impl GenServer
186+
def terminate(reason, _state) do
187+
case reason do
188+
:normal ->
189+
:ok
190+
191+
:shutdown ->
192+
:ok
193+
194+
{:shutdown, _} ->
195+
:ok
196+
197+
other ->
198+
Output.telemetry(
199+
"elixir_ls.dap_server_error",
200+
%{
201+
"elixir_ls.dap_server_error" => inspect(other)
202+
},
203+
%{}
204+
)
205+
206+
Output.debugger_important("Terminating: #{Exception.format_exit(reason)}")
207+
System.stop(1)
208+
end
209+
210+
:ok
211+
end
212+
185213
@impl GenServer
186214
def handle_call(
187215
{:dbg, _binding, %Macro.Env{}, _stacktrace},
@@ -536,14 +564,6 @@ defmodule ElixirLS.Debugger.Server do
536564
{:noreply, state}
537565
end
538566

539-
@impl GenServer
540-
def terminate(reason, _state = %__MODULE__{}) do
541-
if reason != :normal do
542-
Output.debugger_important("Terminating: #{Exception.format_exit(reason)}")
543-
System.stop(1)
544-
end
545-
end
546-
547567
## Helpers
548568

549569
defp handle_request(initialize_req(_, client_info), %__MODULE__{client_info: nil} = state) do

apps/language_server/lib/language_server/build.ex

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ defmodule ElixirLS.LanguageServer.Build do
1010
else
1111
spawn_monitor(fn ->
1212
with_build_lock(fn ->
13-
{us, _} =
13+
{us, result} =
1414
:timer.tc(fn ->
1515
Logger.info("Starting build with MIX_ENV: #{Mix.env()} MIX_TARGET: #{Mix.target()}")
1616

@@ -35,26 +35,40 @@ defmodule ElixirLS.LanguageServer.Build do
3535

3636
diagnostics = Diagnostics.normalize(diagnostics, root_path)
3737
Server.build_finished(parent, {status, mixfile_diagnostics ++ diagnostics})
38-
rescue
39-
e ->
40-
Logger.warning(
41-
"Mix.Dep.load_on_environment([]) failed: #{inspect(e.__struct__)} #{Exception.message(e)}"
38+
:"mix_compile_#{status}"
39+
catch
40+
kind, payload ->
41+
{payload, stacktrace} = Exception.blame(kind, payload, __STACKTRACE__)
42+
message = Exception.format(kind, payload, stacktrace)
43+
Logger.warning("Mix.Dep.load_on_environment([]) failed: #{message}")
44+
45+
JsonRpc.telemetry(
46+
"elixir_ls.build_error",
47+
%{"elixir_ls.build_error" => message},
48+
%{}
4249
)
4350

4451
# TODO pass diagnostic
4552
Server.build_finished(parent, {:error, []})
53+
:deps_error
4654
end
4755

4856
{:error, mixfile_diagnostics} ->
4957
Server.build_finished(parent, {:error, mixfile_diagnostics})
58+
:mixfile_error
5059

5160
:no_mixfile ->
5261
Server.build_finished(parent, {:no_mixfile, []})
62+
:no_mixfile
5363
end
5464
end)
5565

5666
Tracer.save()
5767
Logger.info("Compile took #{div(us, 1000)} milliseconds")
68+
69+
JsonRpc.telemetry("elixir_ls.build", %{"elixir_ls.result" => result}, %{
70+
"elixir_ls.build_time" => div(us, 1000)
71+
})
5872
end)
5973
end)
6074
end
@@ -84,13 +98,11 @@ defmodule ElixirLS.LanguageServer.Build do
8498
Mix.Project.in_project(app, path, [build_path: build_path], fn mix_project ->
8599
mix_project
86100
end)
87-
rescue
88-
e ->
89-
message = Exception.message(e)
90-
91-
Logger.warning(
92-
"Unable to prune mix project module for #{app}: #{inspect(e.__struct__)} #{message} #{Exception.format(:error, e, __STACKTRACE__)}"
93-
)
101+
catch
102+
kind, payload ->
103+
{payload, stacktrace} = Exception.blame(kind, payload, __STACKTRACE__)
104+
message = Exception.format(kind, payload, stacktrace)
105+
Logger.warning("Unable to prune mix project module for #{app}: #{message}")
94106
end
95107

96108
if child_module do
@@ -287,6 +299,13 @@ defmodule ElixirLS.LanguageServer.Build do
287299
:ok
288300
else
289301
Logger.error("mix clean returned #{inspect(results)}")
302+
303+
JsonRpc.telemetry(
304+
"elixir_ls.mix_clean_error",
305+
%{"elixir_ls.mix_clean_error" => inspect(results)},
306+
%{}
307+
)
308+
290309
{:error, :clean_failed}
291310
end
292311
end

apps/language_server/lib/language_server/dialyzer.ex

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,13 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
259259
{:exit, reason}, file_changes ->
260260
# on elixir >= 1.14 reason will actually be {beam_path, reason} but
261261
# it's not easy to pattern match on that
262-
Logger.error(
263-
"[ElixirLS Dialyzer] Unable to process one of the beams: #{inspect(reason)}"
262+
message = "Unable to process one of the beams: #{Exception.format_exit(reason)}"
263+
Logger.error(message)
264+
265+
JsonRpc.telemetry(
266+
"elixir_ls.dialyzer_error",
267+
%{"elixir_ls.dialyzer_error" => message},
268+
%{}
264269
)
265270

266271
file_changes
@@ -415,6 +420,8 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
415420

416421
Logger.info("[ElixirLS Dialyzer] Analysis finished in #{div(us, 1000)} milliseconds")
417422

423+
JsonRpc.telemetry("elixir_ls.dialyzer", %{}, %{"elixir_ls.dialyzer_time" => div(us, 1000)})
424+
418425
analysis_finished(parent, :ok, active_plt, mod_deps, md5, warnings, timestamp, build_ref)
419426
end
420427

@@ -492,6 +499,12 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
492499
"[ElixirLS Dialyzer] get_core_from_beam failed for #{file}: #{inspect(reason)}"
493500
)
494501

502+
JsonRpc.telemetry(
503+
"elixir_ls.dialyzer_error",
504+
%{"elixir_ls.dialyzer_error" => inspect(reason)},
505+
%{}
506+
)
507+
495508
nil
496509
end
497510
end

apps/language_server/lib/language_server/dialyzer/analyzer.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,5 +210,6 @@ defmodule ElixirLS.LanguageServer.Dialyzer.Analyzer do
210210
"Analysis failed: " <> Exception.format_exit(reason) <> "\n" <> Enum.join(log_cache, "\n")
211211

212212
Logger.error(message)
213+
JsonRpc.telemetry("elixir_ls.dialyzer_error", %{"elixir_ls.dialyzer_error" => message}, %{})
213214
end
214215
end

apps/language_server/lib/language_server/dialyzer/manifest.ex

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,28 @@ defmodule ElixirLS.LanguageServer.Dialyzer.Manifest do
2828
:ok
2929

3030
{:DOWN, ^ref, :process, ^pid, reason} ->
31+
error_msg = Exception.format_exit(reason)
32+
3133
JsonRpc.show_message(
3234
:error,
3335
"Unable to build dialyzer PLT. Most likely there are problems with your OTP and elixir installation."
3436
)
3537

36-
Logger.error("Dialyzer PLT build process exited with reason: #{inspect(reason)}")
38+
Logger.error("Dialyzer PLT build process exited with reason: #{error_msg}")
3739

3840
Logger.warning(
3941
"Dialyzer support disabled. Most likely there are problems with your elixir and OTP installation. Visit https://github.com/elixir-lsp/elixir-ls/issues/540 for help"
4042
)
4143

44+
JsonRpc.telemetry(
45+
"elixir_ls.dialyzer_error",
46+
%{
47+
"elixir_ls.dialyzer_error" =>
48+
"Dialyzer PLT build process exited with reason: #{error_msg}"
49+
},
50+
%{}
51+
)
52+
4253
# NOTE We do not call Dialyzer.analysis_finished. LS keeps working and building normally
4354
# only dialyzer is not being triggered after every build
4455
end

apps/language_server/lib/language_server/providers/folding_range/token.ex

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ defmodule ElixirLS.LanguageServer.Providers.FoldingRange.Token do
4242
# raise here?
4343
error ->
4444
Logger.warning("Unmatched token: #{inspect(error)}")
45+
46+
JsonRpc.telemetry(
47+
"elixir_ls.folding_ranges_error",
48+
%{"elixir_ls.folding_ranges_error" => inspect(error)},
49+
%{}
50+
)
51+
4552
:error
4653
end
4754

apps/language_server/lib/language_server/server.ex

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,34 @@ defmodule ElixirLS.LanguageServer.Server do
128128
{:ok, %__MODULE__{}}
129129
end
130130

131+
@impl GenServer
132+
def terminate(reason, _state) do
133+
case reason do
134+
:normal ->
135+
:ok
136+
137+
:shutdown ->
138+
:ok
139+
140+
{:shutdown, _} ->
141+
:ok
142+
143+
other ->
144+
JsonRpc.telemetry(
145+
"elixir_ls.lsp_server_error",
146+
%{
147+
"elixir_ls.lsp_server_error" => inspect(other)
148+
},
149+
%{}
150+
)
151+
152+
Logger.info("Terminating: #{Exception.format_exit(reason)}")
153+
System.stop(1)
154+
end
155+
156+
:ok
157+
end
158+
131159
@impl GenServer
132160
def handle_call({:request_finished, id, result}, _from, state = %__MODULE__{}) do
133161
{{_pid, command, start_time}, requests} = Map.pop!(state.requests, id)
@@ -1379,6 +1407,15 @@ defmodule ElixirLS.LanguageServer.Server do
13791407

13801408
other ->
13811409
Logger.error("client/registerCapability returned: #{inspect(other)}")
1410+
1411+
JsonRpc.telemetry(
1412+
"elixir_ls.reverse_request_error",
1413+
%{
1414+
"elixir_ls.reverse_request_error" => inspect(other),
1415+
"elixir_ls.reverse_request" => "client/registerCapability"
1416+
},
1417+
%{}
1418+
)
13821419
end
13831420
end
13841421

@@ -1397,6 +1434,15 @@ defmodule ElixirLS.LanguageServer.Server do
13971434

13981435
other ->
13991436
Logger.error("client/registerCapability returned: #{inspect(other)}")
1437+
1438+
JsonRpc.telemetry(
1439+
"elixir_ls.reverse_request_error",
1440+
%{
1441+
"elixir_ls.reverse_request_error" => inspect(other),
1442+
"elixir_ls.reverse_request" => "client/registerCapability"
1443+
},
1444+
%{}
1445+
)
14001446
end
14011447
end
14021448

@@ -1604,6 +1650,16 @@ defmodule ElixirLS.LanguageServer.Server do
16041650

16051651
other ->
16061652
Logger.error("Cannot get client configuration: #{inspect(other)}")
1653+
1654+
JsonRpc.telemetry(
1655+
"elixir_ls.reverse_request_error",
1656+
%{
1657+
"elixir_ls.reverse_request_error" => inspect(other),
1658+
"elixir_ls.reverse_request" => "workspace/configuration"
1659+
},
1660+
%{}
1661+
)
1662+
16071663
state
16081664
end
16091665
else
@@ -1676,6 +1732,12 @@ defmodule ElixirLS.LanguageServer.Server do
16761732
Exception.format(:error, e, __STACKTRACE__)
16771733
)
16781734

1735+
JsonRpc.telemetry(
1736+
"elixir_ls.parser_error",
1737+
%{"elixir_ls.parser_error" => Exception.format(:error, e, __STACKTRACE__)},
1738+
%{}
1739+
)
1740+
16791741
{:error, diagnostic}
16801742
end
16811743
end)

apps/language_server/lib/language_server/source_file.ex

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,13 +241,12 @@ defmodule ElixirLS.LanguageServer.SourceFile do
241241
else
242242
{:ok, Mix.Tasks.ElixirLSFormat.formatter_for_file(path)}
243243
end
244-
rescue
245-
e ->
246-
message = Exception.message(e)
244+
catch
245+
kind, payload ->
246+
{payload, stacktrace} = Exception.blame(kind, payload, __STACKTRACE__)
247+
message = Exception.format(kind, payload, stacktrace)
247248

248-
Logger.warning(
249-
"Unable to get formatter options for #{path}: #{inspect(e.__struct__)} #{message} #{Exception.format(:error, e, __STACKTRACE__)}"
250-
)
249+
Logger.warning("Unable to get formatter options for #{path}: #{message}")
251250

252251
:error
253252
end

0 commit comments

Comments
 (0)